JFrame gets decorated with Windows borders, even the Look&Feel is set otherwise

14,303

Add this line in your main method before you init the JFrame

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.

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.

That's from Oracle in reference to that line of code.

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.

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.setDefaultLookAndFeelDecorated(true);
Share:
14,303
Timmos
Author by

Timmos

I'm a Civil Engineer in Computer Science. Programming in Java since 2006, professionally since 2012. Also writing in C++. Interests: GUI's, 3D, 3D rendering, Java, C++, software architecture, OOP, concurrency, math, 3D engines.

Updated on June 23, 2022

Comments

  • Timmos
    Timmos about 2 years

    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.

    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).

    Why is this? Is this new in Java 7? This seems really weird.

    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?