java JFrame 用 Windows 边框装饰,甚至 Look&Feel 设置为其他方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15731541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JFrame gets decorated with Windows borders, even the Look&Feel is set otherwise
提问by Timmos
Good day everyone.
今天是个好日子。
First of all: check this image.
Please note that in the first of the 3 frames, the button is styled with Metal Look and Feel, but the frame is Windows styled. The other 2 frames are "OK" in the sence that the button LAF matches the frame LAF.
请注意,在 3 个框架中的第一个中,按钮采用 Metal 外观和感觉样式,但框架采用 Windows 样式。其他 2 个帧是“OK”,因为按钮 LAF 与帧 LAF 匹配。
The code for all of these (same order as the images):
所有这些的代码(与图像相同的顺序):
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.getContentPane().add(new JButton("button"));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
frame.setSize(100, 100);
frame.getContentPane().add(new JButton("button"));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
// 0 => "javax.swing.plaf.metal.MetalLookAndFeel"
// 3 => the Windows Look and Feel
String name = UIManager.getInstalledLookAndFeels()[3].getClassName();
UIManager.setLookAndFeel(name);
} catch (Exception ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame();
frame.getContentPane().add(new JButton("button"));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
Now what bothers me is that I have never been forced to use the lines frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
, as setting the Look and Feel just worked with the UIManager.setLookAndFeel()
method. Normally, the JFrame itself would get styled too, but this seems not longer the case as I get a Windows styled frame (1st image, 1 code snippet).
现在困扰我的是我从来没有被迫使用线frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
,因为设置外观和感觉只是使用UIManager.setLookAndFeel()
方法。通常,JFrame 本身也会被设置样式,但是当我得到一个 Windows 样式的框架(第一个图像,1 个代码片段)时,情况似乎不再如此。
Why is this? Is this new in Java 7? This seems really weird.
为什么是这样?这是 Java 7 中的新功能吗?这看起来真的很奇怪。
Normally, without touching code that involves Look and Feel, the program should start with the Metal Look and Feel, as this is the standard Java Look and Feel. So why does the first program start with a Windows frame?
通常,在不涉及涉及外观的代码的情况下,程序应该从 Metal 外观和感觉开始,因为这是标准的 Java 外观和感觉。那么为什么第一个程序以 Windows 框架开头呢?
回答by Drew
Add this line in your main method before you init the JFrame
在您初始化 JFrame 之前,在您的 main 方法中添加这一行
JFrame.setDefaultLookAndFeelDecorated(true);
I noticed the same thing a while ago when I started using substance but that line is all it took to fix it.
不久前,当我开始使用 Substance 时,我注意到了同样的事情,但这条线就是修复它所需要的全部。
As the preceding code snippet implies, you must invoke the setDefaultLookAndFeelDecorated method before creating the frame whose decorations you wish to affect. The value you set with setDefaultLookAndFeelDecorated is used for all subsequently created JFrames. You can switch back to using window system decorations by invoking JFrame.setDefaultLookAndFeelDecorated(false). Some look and feels might not support window decorations; in this case, the window system decorations are used.
正如前面的代码片段所暗示的那样,在创建要影响其装饰的框架之前,您必须调用 setDefaultLookAndFeelDecorated 方法。您使用 setDefaultLookAndFeelDecorated 设置的值用于所有随后创建的 JFrame。您可以通过调用 JFrame.setDefaultLookAndFeelDecorated(false) 切换回使用窗口系统装饰。某些外观可能不支持窗口装饰;在这种情况下,使用了窗口系统装饰。
That's from Oraclein reference to that line of code.
这是来自Oracle对那行代码的引用。
This is a feature of Java, by default JFrame Window borders will not be decorated, but using the mentioned function allows the set look and feel to decorate the Window. This feature was implemented in 1.4 from what I can tell.
这是 Java 的一个特性,默认情况下不会装饰 JFrame Window 边框,但使用上述功能允许设置外观来装饰 Window。据我所知,此功能是在 1.4 中实现的。
Edit:
编辑:
Also, if you want to apply your custom look and feel to JDialog window borders, you can use the same static method on the JDialog class in the same place you called it on JFrame:
此外,如果您想将自定义外观应用到 JDialog 窗口边框,您可以在 JDialog 类上使用相同的静态方法,在您在 JFrame 上调用它的同一位置:
JDialog.setDefaultLookAndFeelDecorated(true);
回答by Paaske
I'm guessing that you hane not set the swing.defaultlaf
system environment variable, but maybe you could check if your swing.properties
is present and if it contains an entry swing.defaultlaf
. This could be the reason, see below for how the UIManager chooses L&F.
我猜你没有设置swing.defaultlaf
系统环境变量,但也许你可以检查你swing.properties
是否存在以及它是否包含一个条目swing.defaultlaf
。这可能是原因,请参阅下文了解 UIManager 如何选择 L&F。
I have the file present on my MacBook, obviously, as Apple wants the Apple L&F to be the default. But I have not checked a Windows machine yet..
显然,我的 MacBook 上有该文件,因为 Apple 希望 Apple L&F 成为默认设置。但我还没有检查过 Windows 机器..
Here's an excerpt from the Java 7 documentation which has been pretty much unchanged since Java 1.4. Java 1.4.2, Java 1.5, Java 6, Java 7:
这是 Java 7 文档的摘录,自 Java 1.4 以来几乎没有变化。Java 1.4.2、Java 1.5、Java 6、Java 7:
Default look and feel
默认外观
The class used for the default look and feel is chosen in the following manner:
用于默认外观的类按以下方式选择:
- If the system property
swing.defaultlaf
isnon-null
, use its value as the default look and feel class name. - If the
Properties
fileswing.properties
exists and contains the keyswing.defaultlaf
, use its value as the default look and feel class name. The location that is checked forswing.properties
may vary depending upon the implementation of the Java platform. In Sun's implementation the location is${java.home}/lib/swing.properties
. Refer to the release notes of the implementation being used for further details. - Otherwise use the cross platform look and feel.
- 如果系统属性
swing.defaultlaf
为non-null
,则使用其值作为默认的外观类名称。 - 如果
Properties
文件swing.properties
存在并包含 keyswing.defaultlaf
,则使用其值作为默认外观类名称。检查的位置swing.properties
可能因 Java 平台的实现而异。在 Sun 的实现中,位置是${java.home}/lib/swing.properties
。有关更多详细信息,请参阅正在使用的实现的发行说明。 - 否则使用跨平台外观。