MadJoe
MadJoe

Reputation: 23

JPanel Class with null layout not showing components

So, i created an object of class "CustomPanel" that creates a JPanel with a GridLayout and a label inside of it then I added it to my JFrame. It works fine showing the label "HELLO", but when I change the layout manager of the jpanel to (null) it doesn't show anything. I know, I know using null layout is a very bad practice but I just want to know why it isn't showing the components.

Main class:

import javax.swing.JFrame;

public class MainMenu extends javax.swing.JFrame{

    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Size the window.
        frame.setSize(500, 500);

        CustomPanel panel = new CustomPanel();

        frame.getContentPane().add(panel);

        frame.setVisible(true);
    }

    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

CustomPanel class with GridLayout (This works fine):

import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class CustomPanel extends JPanel{

    public CustomPanel() {
        initUI();
    }

    public final void initUI() {

        // create the panel and set the layout
        JPanel main = new JPanel();
        main.setLayout(new GridLayout());

        // create the labels
        JLabel myLabel = new JLabel("HELLO");

        // add componets to panel
        main.add(myLabel);

        this.add(main);
    }
}

CustomPanel class with Null layout (This doesn't work):

import javax.swing.JLabel;
import javax.swing.JPanel;

public class CustomPanel extends JPanel{

    public CustomPanel() {
        initUI();
    }

    public final void initUI() {

        // create the panel and set the layout
        JPanel main = new JPanel();
        main.setLayout(null);

        // create the labels
        JLabel myLabel = new JLabel("HELLO");
        myLabel.setBounds(10, 10, myLabel.getPreferredSize().width, myLabel.getPreferredSize().height);

        // add componets to panel
        main.add(myLabel);

        this.add(main);
    }
}

The jlabel is correctly set inside the jpanel so it should be showing in the upper-left side of the jframe, but it doesn't. What is causing this? what am I missing?.

Upvotes: 1

Views: 1591

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

The problem is that when you don't use a proper layout manager the main JPanel has a preferred size of 0,0, and won't display within the container that it is placed within. The CustomPanel that holds the main JPanel uses FlowLayout and will use its contained component's preferred sizes to help size and position these components, but since main has no layout, adding the JLabel to main does not increase the preferred size as it should -- yet another reason to use layouts, and CustomPanel will display main as just a sizeless dot. You could of course get around this by giving main a preferred size via main.setPreferredSize(...), but then you'd be solving a kludge with a kludge -- not good. Another possible solution is to change CustomPanel's layout to something else that might expand the main JPanel that it holds, perhaps giving CustomPanel a BorderLayout. In this situation, adding main to CustomPanel in a default fashion will place the main JPanel into the BorderLayout.CENTER position, expanding it to fill CustomPanel, and the JLabel will likely be seen.

The proper solution, of course, is to avoid use of null layouts whenever possible.

Upvotes: 4

Related Questions