简体   繁体   中英

How do I add a JPanel to container from a different class?

Basically I have a class that acts as a container. It's a JFrame that has a constructor that takes a JPanel . Now, I have constructed various JPanels outside the container class. I have them designed this way for specific reasons, mainly to do with the MVC design pattern.

The problem I have is that whenever I add the JPanel to the container, FROM the container class it shows up blank. There is no compiling error. I can't see why it would not add what I ask it to. I'll post some code, this is the container:

public class MainFrame {

    private JFrame mainContainer = new JFrame("Frog Checkers");

    private JPanel frame = new testFrame();

    public void start() {
        mainContainer(frame);
    }

    private JFrame mainContainer(JPanel frame) {
        mainContainer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainContainer.setSize(925, 608);
        mainContainer.setVisible(true);
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        mainContainer.setLocation(dim.width / 2 - mainContainer.getSize().width
            / 2, dim.height / 2 - mainContainer.getSize().height / 2);
        mainContainer.setResizable(false);

        mainContainer.add(frame);

        return mainContainer;
    }
}

And this is an example of one JPanel i'm trying to add:

public class testFrame extends JPanel {
    private JPanel testPanel = new JPanel()
    private JButton testButton, anotherButton;

    public testFrame() {
        testPanel.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        testButton = new JButton("New Button");
        constraints.gridx = 0; // Location on grid
        constraints.gridy = 3; // Location on grid
        constraints.gridwidth = 2; // How many grids the width will consume
        constraints.gridheight = 1; // How many grids the length will consume
        constraints.weightx = 1.0; // for resizing
        constraints.weighty = 1.0; // for resizing
        constraints.anchor = GridBagConstraints.SOUTHWEST; // Where it will be anchored
        constraints.ipadx = 20; // Internal padding
        constraints.ipady = 20; // Inernal padding
        constraints.insets = new Insets(50,50,50,50);
        testPanel.add(testButton, constraints);

        anotherButton = new JButton("another Button");
        constraints.gridx = 0; // Location on grid
        constraints.gridy = 3; // Location on grid
        constraints.gridwidth = 2; // How many grids the width will consume
        constraints.gridheight = 1; // How many grids the length will consume
        constraints.weightx = 1.0; // for resizing
        constraints.weighty = 1.0; // for resizing
        constraints.anchor = GridBagConstraints.SOUTHWEST; // Where it will be anchored
        constraints.ipadx = 20; // Internal padding
        constraints.ipady = 20; // Inernal padding
        constraints.insets = new Insets(50, 50, 120, 80);
        testPanel.add(anotherButton, constraints);
    }
}

I am using GridBagLayout because I been told numerous times to not use a null layout. But if anyone knows a way to get around using a null layout, please share. And to be a bit clearer, all this code would work IF I had it all as a method within the container class, but I don't want it that way. Any ideas would be greatly appreciated.

The problem is with your testFrame class. It extends JPanel and inside it you took another JPanel which is not necessary. If you insist to take, you have to add it to the testFrame using the statement add(testPanel); in the end of the constructor of testFrame .

Class name should start with a capital letter . I suggest to rename your class as TestFrame instead of testFrame .

public class testFrame extends JPanel {
    private JButton testButton, anotherButton;

    public testFrame() {
        setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        testButton = new JButton("New Button");
        constraints.gridx = 0; // Location on grid
        constraints.gridy = 3; // Location on grid
        constraints.gridwidth = 2; // How many grids the width will consume
        constraints.gridheight = 1; // How many grids the length will consume
        constraints.weightx = 1.0; // for resizing
        constraints.weighty = 1.0; // for resizing
        constraints.anchor = GridBagConstraints.SOUTHWEST; // Where it will be anchored
        constraints.ipadx = 20; // Internal padding
        constraints.ipady = 20; // Inernal padding
        constraints.insets = new Insets(50,50,50,50);
        add(testButton, constraints);

        anotherButton = new JButton("another Button");
        constraints.gridx = 0; // Location on grid
        constraints.gridy = 3; // Location on grid
        constraints.gridwidth = 2; // How many grids the width will consume
        constraints.gridheight = 1; // How many grids the length will consume
        constraints.weightx = 1.0; // for resizing
        constraints.weighty = 1.0; // for resizing
        constraints.anchor = GridBagConstraints.SOUTHWEST; // Where it will be anchored
        constraints.ipadx = 20; // Internal padding
        constraints.ipady = 20; // Inernal padding
        constraints.insets = new Insets(50, 50, 120, 80);
        add(anotherButton, constraints);
    }
}

And in MainFrame , use

getContentPane().add([testFrame object]);

Agree with Ravindra that directly using JFrame.getContentPane() is best practice. The other thing you probably should do is give that ContentPane an explicit layout (similar to what you did with your JPanel). Something like:

mainContainer.getContentPane().setLayout(new BorderLayout());
mainContainer.getContentPane().add(yourPanel, BorderLayout.CENTER);

You can choose any layout you want, but I often select BorderLayout for my main frames because the CENTER area is "greedy" (whatever you put there will automatically try to fill the space), and that's often desired behavior.

Other things that might help include using the fill property in GridBagConstraints to notify it to attempt to fill your entire panel area, and overriding your Panel's getPreferredSize() to give your layout a size hint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM