微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 setWindowDecorationStyle(JRootPane.FRAME) 调整大小时的 Java JFrame 奇怪行为;

如何解决使用 setWindowDecorationStyle(JRootPane.FRAME) 调整大小时的 Java JFrame 奇怪行为;

我正在创建一个 JFrame,使用名为 FlatLaf自定义外观。但是当我调整窗口大小时,我遇到了奇怪的行为。我可以用这个片段复制完全相同的问题:

import com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme;
import javax.swing.*;
import java.awt.*;

public class Main{
    public static void main(String[] args){

        try{ UIManager.setLookAndFeel(new FlatOneDarkIJTheme()); }
        catch(Exception e){}

        JFrame frame = new JFrame();
        frame.setSize(1280,720);
        frame.setMinimumSize(new Dimension(750,400));
        frame.setLocationRelativeto(null);
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

        frame.setUndecorated(true);
        frame.getRootPane().setwindowdecorationStyle(JRootPane.FRAME);

        frame.setVisible(true);
    }
}

这样我就可以得到我需要的东西,这个: JFrame with Look and Feel

为了实现这一点,我使用了说明 frame.setUndecorated(true);frame.getRootPane().setwindowdecorationStyle(JRootPane.FRAME);(因为正如我所说,我不想要认的系统边框,像这样:Frame with default system border

问题是当我从框架的左侧和顶部调整大小时,它开始朝那个方向移动,但我还没有找到解决方案,这是一个 gif 显示JFrame with weird resize behavior

当我删除这些行时,这个问题显然解决了:

frame.setUndecorated(true);
frame.getRootPane().setwindowdecorationStyle(JRootPane.FRAME);

因为我找回了系统边框,但这不是我想要的。

我该如何解决这个问题?有没有更好的方法(或不同的方法)?

解决方法

问题是当我从框架的左侧和顶部调整大小时,它开始朝那个方向移动

发生这种效果是因为您设置了 JFrame 的最小尺寸,一起,同时您清除了框架装饰。所以不要设置最小尺寸,或者只是启用装饰。如果您启用装饰并仍然设置最小尺寸,那么用户将能够调整框架的大小,直到它达到相应的最小尺寸,框架将保持原位,而不是移动。


至于标题栏,万一你需要它所有好的特性(比如右边的3个按钮,左边的框架的标题和图标,中间的栏实际上可以拖动用户移动框架),但您也希望它具有特定的颜色,然后不要取消装饰它,只更改标题栏组件的颜色,可以这样做:

import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatLaf;
import javax.swing.*;
import java.awt.*;

public class Main {
    public static void main(final String[] args) {
        final FlatDarkLaf laf = new FlatDarkLaf();
        FlatLaf.install(laf);
        final Color controlColor = laf.getDefaults().getColor("control"); //Obtains the background color of FlatDarkLaf.

        //Change the title bar active and inactive color...
        UIManager.put("TitlePane.inactiveBackground",controlColor); //This is the color of the title bar when the frame doesn't have focus.
        UIManager.put("TitlePane.background",controlColor); //This is the color of the title bar when the frame has focus.
        
        final JFrame frame = new JFrame("Title");
        
        frame.setSize(1280,720);
        frame.setMinimumSize(new Dimension(750,400));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

在这种情况下,您必须启用装饰。但这似乎没问题,因为您想要标题栏的特征,只是其中的背景颜色不同。

我在 the source code of the class FlatTitlePane 的文档中发现了属性/键 "TitlePane.inactiveBackground""TitlePane.background",有人可以看到(在 the source code of FlatRootPaneUI 中)这是正在安装的类在框架的根窗格上作为其标题栏。

我已经看到 the source code of FlatLaf 中的 laf.getDefaults().getColor("control"); 部分(在 getDefaults 方法中)。

根据some instructions of the FlatLaf's web page,您最好在安装 LAF 之后和创建组件之前设置这些属性。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。