java - JFrame 装饰有 Windows 边框,即使 Look&Feel 设置为其他方式

标签 java swing jframe look-and-feel

大家好。

首先:检查这张图片。

请注意,在 3 个框架中的第一个框架中,按钮采用金属外观风格,但框架采用 Windows 风格。在按钮 LAF 与框架 LAF 匹配的情况下,其他 2 个框架是“OK”的。

所有这些的代码(与图像的顺序相同):

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);
        }
    });
}

现在困扰我的是,我从来没有被迫使用行 frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);,因为设置外观仅适用于 UIManager.setLookAndFeel() 方法。通常,JFrame 本身也会设置样式,但当我获得 Windows 样式的框架(第 1 张图像,1 个代码片段)时,情况似乎不再如此。

这是为什么?这是 Java 7 中的新功能吗?这看起来真的很奇怪。

通常,在不涉及涉及外观的代码的情况下,程序应该从 Metal 外观开始,因为这是标准的 Java 外观。那么,为什么第一个程序以 Windows 框架开始?

最佳答案

在初始化 JFrame 之前在您的主要方法中添加这一行

JFrame.setDefaultLookAndFeelDecorated(true);

不久前,当我开始使用 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.

来自 Oracle引用那行代码。

这是Java的一个特性,默认情况下JFrame Window的边框是不会被装饰的,但是使用上面提到的函数可以让设置的外观来装饰Window。据我所知,此功能已在 1.4 中实现。

编辑:

此外,如果您想将自定义外观应用到 JDialog 窗口边框,您可以在 JDialog 类上使用与在 JFrame 上调用它的相同位置的相同静态方法:

JDialog.setDefaultLookAndFeelDecorated(true);

关于java - JFrame 装饰有 Windows 边框,即使 Look&Feel 设置为其他方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15731541/

相关文章:

Java Hibernate 多对一问题

java - setContentPane() 和 getContentPane().add() 都不起作用

java - 数据截断 : Incorrect datetime value: '' for column 'date' at row 1

java - Swing 事件调度线程是否以比主线程更高的优先级运行?

java - 在 Java JFrame 中显示图像

java - 如何在不创建新图表的情况下将 jzy3d 图表添加到 JFrame?

java - 防止 JFrame 显示任何图标

java - 命令模式如何将发送者与接收者解耦?

java - 如何使用 JOptionPane 删除 ArrayList 中的元素?

java - 为什么 Solr 在无模式模式下为 String 创建多值字段?