Java 使用 setWindowDecorationStyle(JRootPane.FRAME) 调整大小时,JFrame 出现奇怪的行为;
Java JFrame weird behavior when resizing with setWindowDecorationStyle(JRootPane.FRAME);
我正在创建一个 JFrame
,使用名为 FlatLaf 的自定义外观。但是当我调整 window 大小时我遇到了奇怪的行为。我可以用这个片段复制完全相同的问题:
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);
因为我找回了系统边框,但这不是我想要的。
我该如何解决这个问题?有没有更好的方法(或不同的方法)?
The problem is when I resize from the left and the top of the frame, it starts to move in that direction
之所以会出现这种效果,是因为您同时设置了 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
which as someone can see (in the source code of FlatRootPaneUI
的文档中发现了 properties/keys "TitlePane.inactiveBackground"
和 "TitlePane.background"
)这是在根窗格上安装的 class框架的标题栏。
我在 the source code of FlatLaf
中看到了 laf.getDefaults().getColor("control");
部分(在 getDefaults
方法中)。
根据 some instructions of the FlatLaf's web page,您最好在安装 LAF 之后和创建组件之前设置这些属性。
我正在创建一个 JFrame
,使用名为 FlatLaf 的自定义外观。但是当我调整 window 大小时我遇到了奇怪的行为。我可以用这个片段复制完全相同的问题:
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);
因为我找回了系统边框,但这不是我想要的。
我该如何解决这个问题?有没有更好的方法(或不同的方法)?
The problem is when I resize from the left and the top of the frame, it starts to move in that direction
之所以会出现这种效果,是因为您同时设置了 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
which as someone can see (in the source code of FlatRootPaneUI
的文档中发现了 properties/keys "TitlePane.inactiveBackground"
和 "TitlePane.background"
)这是在根窗格上安装的 class框架的标题栏。
我在 the source code of FlatLaf
中看到了 laf.getDefaults().getColor("control");
部分(在 getDefaults
方法中)。
根据 some instructions of the FlatLaf's web page,您最好在安装 LAF 之后和创建组件之前设置这些属性。