简体   繁体   English

如何从不同的类向容器添加JPanel?

[英]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 . 这是一个JFrame ,具有一个采用JPanel的构造函数。 Now, I have constructed various JPanels outside the container class. 现在,我在容器类之外构造了各种JPanels。 I have them designed this way for specific reasons, mainly to do with the MVC design pattern. 我出于某些特定原因设计了这种方法,主要是与MVC设计模式有关。

The problem I have is that whenever I add the JPanel to the container, FROM the container class it shows up blank. 我的问题是,每当我将JPanel添加到容器中时,从容器类中将其显示为空白。 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: 这是我尝试添加的一个JPanel的示例:

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. 我之所以使用GridBagLayout,是因为我多次被告知不要使用null布局。 But if anyone knows a way to get around using a null layout, please share. 但是,如果有人知道使用null布局的方法,请分享。 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. 问题出在您的testFrame类上。 It extends JPanel and inside it you took another JPanel which is not necessary. 扩展了 JPanel并且在其中使用了另一个不必要的JPanel If you insist to take, you have to add it to the testFrame using the statement add(testPanel); 如果坚持使用,则testFrame使用语句add(testPanel);将其添加到add(testPanel); in the end of the constructor of testFrame . testFrame的构造函数的testFrame

Class name should start with a capital letter . 类名应以大写字母开头 I suggest to rename your class as TestFrame instead of testFrame . 我建议将您的类重命名为TestFrame而不是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 然后在MainFrame中使用

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

Agree with Ravindra that directly using JFrame.getContentPane() is best practice. 同意Ravindra的观点,直接使用JFrame.getContentPane()是最佳实践。 The other thing you probably should do is give that ContentPane an explicit layout (similar to what you did with your JPanel). 您可能应该做的另一件事是给ContentPane一个明确的布局(类似于您对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. 您可以选择所需的任何布局,但是我经常为我的主框架选择BorderLayout,因为CENTER区域是“贪婪的”(无论放置在哪里,都会自动尝试填充该空间),而这通常是理想的行为。

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. 其他可能有帮助的事情包括使用GridBagConstraints中的fill属性来通知它尝试填充整个面板区域,并覆盖Panel的getPreferredSize()来为布局提供尺寸提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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