0

When running code that instantiates this class:

static final class MyFrame extends JFrame {
    private CardLayout layout = new CardLayout();

    public MyFrame() {
        setLayout(layout);
        System.out.println(getLayout());
    }
}

The results that are printed are:

java.awt.BorderLayout[hgap=0,vgap=0]

Which is JFrames default layout. The layout is not changed. But, if I change

setLayout(layout);

to

getContentPane().setLayout(layout)

getLayout() will print the correct layout.

MVCEs:

Not setting layout:

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            MyFrame frame = new MyFrame();
            frame.setVisible(true);
        });
    }

    static final class MyFrame extends JFrame {
        private CardLayout layout = new CardLayout();

        public MyFrame() {
            setLayout(layout);
            System.out.println(getLayout());
        }
    }
}

Setting layout:

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            MyFrame frame = new MyFrame();
            frame.setVisible(true);
        });
    }

    static final class MyFrame extends JFrame {
        private CardLayout layout = new CardLayout();

        public MyFrame() {
            getContentPane().setLayout(layout);
            System.out.println(getLayout());
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Vince
  • 14,470
  • 7
  • 39
  • 84

1 Answers1

5

I think you're missing something somewhere. Here are the results on my pc using and

setLayout(layout);
System.out.println(getContentPane().getLayout()); // CardLayout is printed
System.out.println(getLayout()); // BorderLayout is printed

getContentPane().setLayout(layout);
System.out.println(getContentPane().getLayout()); // CardLayout is printed
System.out.println(getLayout()); // BorderLayout is printed

Why isn't CardLayout always printed?

Because, unlike JFrame#setLayout(LayoutManager), JFrame#getLayout() does not make a call to its contentPane().

As a matter of fact, JFrame#getLayout() is actually inherited from Container#getLayout() which will return the actual LayoutManager from the actual component (in this case JFrame and not its contentPane()).


JFrame#setLayout

Sets the LayoutManager. Overridden to conditionally forward the call to the contentPane. Refer to RootPaneContainer for more information.

Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89