在JFrame中从另一个类添加JPanel到JPanel

时间:2022-02-08 11:10:31

I can't get my JFrame from main class to display JPanel from another class. Everything compiles without errors.

我无法从主类获得JFrame来显示另一个类的JPanel。所有的编译没有错误。

JFrameTest.java:

JFrameTest.java:

package jframetest;import java.awt.FlowLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;public class JFrameTest extends JFrame {    public JFrameTest() {        FlowLayout mainLayout = new FlowLayout();        setSize(320, 480);        setResizable(false);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setLayout(mainLayout);        JPanel panelMain = new JPanel(mainLayout);        JButton testButton = new JButton("Test12");        panelMain.add(testButton);        JPanelOne panel = new JPanelOne();        panelMain.add(panel);        panel.setVisible(true);        add(panelMain);    }    public static void main(String[] arguments) {        JFrameTest frame = new JFrameTest();        frame.setVisible(true);    }}

JPanelOne.java:

JPanelOne.java:

package jframetest;import java.awt.FlowLayout;import javax.swing.JButton;import javax.swing.JPanel;public class JPanelOne extends JPanel {    public JPanelOne() {        FlowLayout layoutPanel = new FlowLayout();        JPanel panel = new JPanel(layoutPanel);        JButton button = new JButton("test");        panel.add(button);        panel.setVisible(true);    }}

Is it good practice to keep diffrent JPanels in their own classes? (Example: Wanting to have JFrame contain few same size JPanels, which will be switched by setting setVisible() to true/false)

在他们自己的课堂上保持不同的jpanel是一个好习惯吗?(示例:要让JFrame包含几个相同大小的jpanel,可以将setVisible()设置为true/false)进行切换)

EDIT

编辑

Thank you for all your answers. Noted. Now back to my question:

谢谢你的回答。指出。现在回到我的问题:

Now that I know how to add single GUI elements created in other classes I want to know if it is possible to organize elements with layout manager in one of the classes (maybe in some other container than JPanel), so I can add them as a group organized in a layout (thats why I was asking about creating whole JPanel in other class). As on the picture:

现在我知道如何添加一个GUI元素中创建其他类我想知道如果它是可能的组织元素布局管理器的一个类(可能在其他容器比JPanel),这样我就可以把它们作为一个团体组织在一个布局(这就是为什么我问关于创建整个JPanel在其他类)。如照片:

在JFrame中从另一个类添加JPanel到JPanel

JPanel (that 2nd class) code for this example would be:

这个例子的JPanel(第二类)代码是:

package jframetest;import java.awt.*;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JSeparator;import net.miginfocom.swing.MigLayout;public class JPanelOne extends JPanel {    private JPanel panelSettingsMain;    private JLabel labelChooseLanguage, labelWordsCollection;    private JButton buttonSelectLanguage, buttonSelectCollection,            buttonStatistics, buttonPrintingOptions, buttonAddNewWordCollection,            buttonInterfaceCustomization;    private JSeparator separatorSettingsOne, separatorSettingsTwo,            separatorSettingsThree, separatorSettingsFour,            separatorSettingsFive;    private Color greenRegular, separatorGreenLight, separatorGreenDark;    public JPanelOne() {        // creating settings main panel        // setting up layout managers        MigLayout layoutSettingsMain = new MigLayout(                "insets 3 0 0 0");        // setting up colors        greenRegular = new Color(30, 165, 145);        separatorGreenLight = new Color(190, 240, 220);        separatorGreenDark = new Color(130, 205, 180);        panelSettingsMain = new JPanel(layoutSettingsMain);        panelSettingsMain.setBackground(Color.WHITE);            // setting up choose language label            labelChooseLanguage = new JLabel("Choose language:");            panelSettingsMain.add(labelChooseLanguage,                    "gapleft 10, gaptop 15, width 200");            // setting up select language button            buttonSelectLanguage = new JButton("language");            buttonSelectLanguage.setForeground(greenRegular);            buttonSelectLanguage.setFocusPainted(false);            buttonSelectLanguage.setBorder(null);            buttonSelectLanguage.setContentAreaFilled(false);            buttonSelectLanguage.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonSelectLanguage, "gapbottom 15px, wrap");            // setting up light separator            separatorSettingsOne = new JSeparator();            separatorSettingsOne.setForeground(separatorGreenLight);            panelSettingsMain.add(separatorSettingsOne,                    "span 2, width 320, gapbottom 15, wrap");            // setting up words collection label            labelWordsCollection = new JLabel("Words collection:");            panelSettingsMain.add(labelWordsCollection, "gapleft 10");            // setting up selectcollection button            buttonSelectCollection = new JButton("collection");            buttonSelectCollection.setForeground(greenRegular);            buttonSelectCollection.setFocusPainted(false);            buttonSelectCollection.setBorder(null);            buttonSelectCollection.setContentAreaFilled(false);            buttonSelectCollection.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonSelectCollection,                    "gapbottom 15px, wrap");            // setting up dark separator            separatorSettingsTwo = new JSeparator();            separatorSettingsTwo.setForeground(separatorGreenDark);            panelSettingsMain.add(separatorSettingsTwo,                    "span 2, width 320, gapbottom 15px, wrap");            // setting up show statistics button            buttonStatistics = new JButton("Show statistics");            buttonStatistics.setForeground(greenRegular);            buttonStatistics.setFocusPainted(false);            buttonStatistics.setBorder(null);            buttonStatistics.setContentAreaFilled(false);            buttonStatistics.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonStatistics,                    "gapleft 10, gapbottom 15px, , wrap");            // setting up dark separator            separatorSettingsThree = new JSeparator();            separatorSettingsThree.setForeground(separatorGreenDark);            panelSettingsMain.add(separatorSettingsThree,                    "span 2, width 320, gapbottom 15px, wrap");            // setting up printing options button            buttonPrintingOptions = new JButton("Printing options");            buttonPrintingOptions.setForeground(greenRegular);            buttonPrintingOptions.setFocusPainted(false);            buttonPrintingOptions.setBorder(null);            buttonPrintingOptions.setContentAreaFilled(false);            buttonPrintingOptions.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonPrintingOptions,                    "gapleft 10, gapbottom 15px, wrap");            // setting up dark separator            separatorSettingsFour = new JSeparator();            separatorSettingsFour.setForeground(separatorGreenDark);            panelSettingsMain.add(separatorSettingsFour,                    "span 2, width 320, gapbottom 15px, wrap");            // setting up add new word collection button            buttonAddNewWordCollection = new JButton("Add new word collection");            buttonAddNewWordCollection.setForeground(greenRegular);            buttonAddNewWordCollection.setFocusPainted(false);            buttonAddNewWordCollection.setBorder(null);            buttonAddNewWordCollection.setContentAreaFilled(false);            buttonAddNewWordCollection.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonAddNewWordCollection,                    "gapleft 10, gapbottom 15px, , wrap");            // setting up dark separator            separatorSettingsFive = new JSeparator();            separatorSettingsFive.setForeground(separatorGreenDark);            panelSettingsMain.add(separatorSettingsFive,                    "span 2, width 320, gapbottom 10px, wrap");            // setting up interface customization button            buttonInterfaceCustomization = new JButton(                    "Interface customization");            buttonInterfaceCustomization.setForeground(greenRegular);            buttonInterfaceCustomization.setFocusPainted(false);            buttonInterfaceCustomization.setBorder(null);            buttonInterfaceCustomization.setContentAreaFilled(false);            buttonInterfaceCustomization.setCursor(new java.awt.Cursor(                    java.awt.Cursor.HAND_CURSOR));            panelSettingsMain.add(buttonInterfaceCustomization,                    "gapleft 10, gapbottom 15px, wrap");    }}

I was thinking about navigating through the program GUI by setting JPanels (ones like in the example) to visible or not visible.

我正在考虑通过将jpanel(例如本例中的)设置为可见或不可见来在程序GUI中导航。

  1. Is it good way to do it?
  2. 这样做好吗?
  3. Should I split my GUI into few classes, or I should keep everything in one? I am asking, because now with only half of the GUI in the code its about 400 lines long (and it cant do anything than just "look" at this point). As I had said before - I am beginner and its one of the longest application I have written so far (which I am sure it is not that long anyway!).
  4. 我应该把我的GUI分成几个类,还是应该把所有东西都放在一个类中?我在问,因为现在代码中只有一半的GUI有大约400行(而且它不能做任何事情,只能在这一点上“看”)。就像我之前说过的——我是初学者,也是到目前为止我所写的最长的应用程序之一(我相信我写的也不会那么长!)

EDIT

编辑

Maybe I am overthinking it, so in the end is it ok to have big GUI classes and to control visibility of different GUI areas by setting them visible or not?

也许我想得太多了,所以最终是否可以使用大GUI类,并通过设置它们是否可见来控制不同GUI区域的可见性?

EDIT

编辑

I've looked into the CardLayout tutorial at Oracle and it looks like it is good for my task (excluding the creating JPanels from the external classes, but it is ok). I misunderstood it at first and was thinking about CardLayout only in terms of tabbed pane (which I didn't want to implement in my project).

我已经查看了Oracle的CardLayout教程,它看起来对我的任务很好(不包括从外部类创建jpanel,但它是可以的)。我一开始误解了它,只考虑了选项卡窗格(我不想在我的项目中实现它)方面的CardLayout。

4 个解决方案

#1


6  

First to answer your question, you need to add an instance of your panel to the frame with something like this in your JFrameTest constructor:

首先,要回答你的问题,你需要在你的JFrameTest构造函数中添加一个面板实例,比如:

add(new JPanelOne());

You also need to add your button directly to JPanelOne itself:

您还需要直接将按钮添加到JPanelOne本身:

public class JPanelOne extends JPanel {     public JPanelOne() {       JButton button = new JButton("test");       add(button);     }   }

Second, I believe there is a problem with these lines of code:

其次,我认为这些代码行存在问题:

    FlowLayout mainLayout = new FlowLayout();     // snip...    setLayout(mainLayout);     JPanel panelMain = new JPanel(mainLayout); 

Each container should have its own instance of a layout manager. Otherwise your GUI will do strange things:

每个容器都应该有自己的布局管理器实例。否则,您的GUI将做一些奇怪的事情:

setLayout(new FlowLayout());JPanel panelMain = new JPanel(mainLayout);

#2


5  

With some more help (user "Hilek" from some other site) I menaged to get the JPanel from another class to be displeyed in main class. Here is the code:

通过更多的帮助(来自其他站点的用户“Hilek”),我修复了JPanel,以便在主类中被驱散。这是代码:

JFrameTest.java:

JFrameTest.java:

import java.awt.Color;import java.awt.Dimension;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;public class JFrameTest extends JFrame {        private JButton testButton;        private JPanel panelMain;        private JPanelOne panel;        public JFrameTest() {                // setting up JFrame                setLayout(null);                setPreferredSize(new Dimension(420, 90));                setResizable(false);                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                // creating main JPanel (white)                panelMain = new JPanel();                panelMain.setBackground(Color.WHITE);                panelMain.setBounds(0, 0, 420, 90);                panelMain.setPreferredSize(new Dimension(200, 40));                add(panelMain);                // creating JButton in the main JPanel (white)                testButton = new JButton("Button from main class");                panelMain.add(testButton);                // creating new JPanelOne object from JPanelOne class containing black JPanel                panel = new JPanelOne();                // adding black JPanel to main JPanel (white)                panelMain.add(panel);                pack();        }        public static void main(String[] arguments) {                // creating JFrame object and setting it visible                JFrameTest frame = new JFrameTest();                frame.setVisible(true);        }}

JPanelOne.java:

JPanelOne.java:

import java.awt.Color;import java.awt.Dimension;import javax.swing.JButton;import javax.swing.JPanel;import javax.swing.SwingConstants;public class JPanelOne extends JPanel{        public JPanelOne()        {                // setting up black JPanel                JPanel panel = new JPanel();                panel.setPreferredSize(new Dimension(220, 40));                panel.setBackground(Color.BLACK);                // creating button on external JPanel                JButton button = new JButton("Button (+JPanel) from external class");                // adding button to the black JPanel                panel.add(button);                // adding blackJPanel                add(panel);        }}

Print screen of working example:

工作示例打印屏幕:

http://i.stack.imgur.com/qKeBp.jpg

http://i.stack.imgur.com/qKeBp.jpg

Maybe someone will find it helpful in their problem.

也许有人会发现这对他们的问题有帮助。

#3


4  

The problem comes from the JPanelOne class. It inherits JPanel but in the constructor, you create a new JPanel and then you add a button to it. If you do this instead:

问题来自JPanelOne类。它继承了JPanel,但是在构造函数中,您将创建一个新的JPanel,然后向它添加一个按钮。如果你这样做:

public class JPanelOne extends JPanel {   public JPanelOne() {       JButton button = new JButton("test");       add(button);   }}

it should work as you expect it.

它应该像你期望的那样工作。

#4


4  

Don't call setSize() on your JFrame. Instead let the layouts set the proper sizes of their components and the GUI. After adding all components to your GUI, call pack() on the JFrame, then call setVisble(true). Note that most layouts respect a component's preferredSize more so than its size.

不要在JFrame上调用setSize()。相反,让布局设置适当大小的组件和GUI。在将所有组件添加到GUI之后,在JFrame上调用pack(),然后调用setVisble(true)。注意,大多数布局更看重组件的首选大小而不是大小。

Also, your calling setVisible(true)on your individual components is unnecessary (unless you are changing their visibility after the GUI is up and running for some reason). You'll also want to read up more on using layout managers and will probably use FlowLayout less once you've studied them.

另外,您对单个组件的调用setVisible(true)是不必要的(除非您在GUI启动并运行之后更改它们的可见性)。您还需要阅读更多关于使用布局管理器的内容,并且在研究它们之后,可能会减少使用FlowLayout。

Edit
Regarding your recent Edit:

关于你最近的编辑:

Maybe I am overthinking it, so in the end is it ok to have big GUI classes and to control visiblity of diffrent GUI areas by setting them visible or not?

也许我想得太多了,所以最终是否可以使用大GUI类,并通过设置它们是否可见来控制不同GUI区域的可见性?

I will answer that sometimes this is helpful, for instance if you want to change a standard calculator into a scientific calculator, sometimes it's good to simply show an already created JPanel filled with the advance calculation buttons by using setVisible(true). If on the other hand you want to swap "views" of your GUI to reflect a substantial change in its state, for instance a word processor changing from edit mode to print mode, you could swap JPanels easily to do this using a CardLayout.

我将回答,有时这是有用的,例如,如果您想将标准计算器更改为科学计算器,有时最好只显示一个已经创建的、使用setVisible(true)填充了advance计算按钮的JPanel。另一方面,如果您想要交换GUI的“视图”,以反映GUI状态的重大变化,例如一个从编辑模式更改为打印模式的字处理器,您可以使用CardLayout轻松地交换jpanel。

#1


6  

First to answer your question, you need to add an instance of your panel to the frame with something like this in your JFrameTest constructor:

首先,要回答你的问题,你需要在你的JFrameTest构造函数中添加一个面板实例,比如:

add(new JPanelOne());

You also need to add your button directly to JPanelOne itself:

您还需要直接将按钮添加到JPanelOne本身:

public class JPanelOne extends JPanel {     public JPanelOne() {       JButton button = new JButton("test");       add(button);     }   }

Second, I believe there is a problem with these lines of code:

其次,我认为这些代码行存在问题:

    FlowLayout mainLayout = new FlowLayout();     // snip...    setLayout(mainLayout);     JPanel panelMain = new JPanel(mainLayout); 

Each container should have its own instance of a layout manager. Otherwise your GUI will do strange things:

每个容器都应该有自己的布局管理器实例。否则,您的GUI将做一些奇怪的事情:

setLayout(new FlowLayout());JPanel panelMain = new JPanel(mainLayout);

#2


5  

With some more help (user "Hilek" from some other site) I menaged to get the JPanel from another class to be displeyed in main class. Here is the code:

通过更多的帮助(来自其他站点的用户“Hilek”),我修复了JPanel,以便在主类中被驱散。这是代码:

JFrameTest.java:

JFrameTest.java:

import java.awt.Color;import java.awt.Dimension;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;public class JFrameTest extends JFrame {        private JButton testButton;        private JPanel panelMain;        private JPanelOne panel;        public JFrameTest() {                // setting up JFrame                setLayout(null);                setPreferredSize(new Dimension(420, 90));                setResizable(false);                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                // creating main JPanel (white)                panelMain = new JPanel();                panelMain.setBackground(Color.WHITE);                panelMain.setBounds(0, 0, 420, 90);                panelMain.setPreferredSize(new Dimension(200, 40));                add(panelMain);                // creating JButton in the main JPanel (white)                testButton = new JButton("Button from main class");                panelMain.add(testButton);                // creating new JPanelOne object from JPanelOne class containing black JPanel                panel = new JPanelOne();                // adding black JPanel to main JPanel (white)                panelMain.add(panel);                pack();        }        public static void main(String[] arguments) {                // creating JFrame object and setting it visible                JFrameTest frame = new JFrameTest();                frame.setVisible(true);        }}

JPanelOne.java:

JPanelOne.java:

import java.awt.Color;import java.awt.Dimension;import javax.swing.JButton;import javax.swing.JPanel;import javax.swing.SwingConstants;public class JPanelOne extends JPanel{        public JPanelOne()        {                // setting up black JPanel                JPanel panel = new JPanel();                panel.setPreferredSize(new Dimension(220, 40));                panel.setBackground(Color.BLACK);                // creating button on external JPanel                JButton button = new JButton("Button (+JPanel) from external class");                // adding button to the black JPanel                panel.add(button);                // adding blackJPanel                add(panel);        }}

Print screen of working example:

工作示例打印屏幕:

http://i.stack.imgur.com/qKeBp.jpg

http://i.stack.imgur.com/qKeBp.jpg

Maybe someone will find it helpful in their problem.

也许有人会发现这对他们的问题有帮助。

#3


4  

The problem comes from the JPanelOne class. It inherits JPanel but in the constructor, you create a new JPanel and then you add a button to it. If you do this instead:

问题来自JPanelOne类。它继承了JPanel,但是在构造函数中,您将创建一个新的JPanel,然后向它添加一个按钮。如果你这样做:

public class JPanelOne extends JPanel {   public JPanelOne() {       JButton button = new JButton("test");       add(button);   }}

it should work as you expect it.

它应该像你期望的那样工作。

#4


4  

Don't call setSize() on your JFrame. Instead let the layouts set the proper sizes of their components and the GUI. After adding all components to your GUI, call pack() on the JFrame, then call setVisble(true). Note that most layouts respect a component's preferredSize more so than its size.

不要在JFrame上调用setSize()。相反,让布局设置适当大小的组件和GUI。在将所有组件添加到GUI之后,在JFrame上调用pack(),然后调用setVisble(true)。注意,大多数布局更看重组件的首选大小而不是大小。

Also, your calling setVisible(true)on your individual components is unnecessary (unless you are changing their visibility after the GUI is up and running for some reason). You'll also want to read up more on using layout managers and will probably use FlowLayout less once you've studied them.

另外,您对单个组件的调用setVisible(true)是不必要的(除非您在GUI启动并运行之后更改它们的可见性)。您还需要阅读更多关于使用布局管理器的内容,并且在研究它们之后,可能会减少使用FlowLayout。

Edit
Regarding your recent Edit:

关于你最近的编辑:

Maybe I am overthinking it, so in the end is it ok to have big GUI classes and to control visiblity of diffrent GUI areas by setting them visible or not?

也许我想得太多了,所以最终是否可以使用大GUI类,并通过设置它们是否可见来控制不同GUI区域的可见性?

I will answer that sometimes this is helpful, for instance if you want to change a standard calculator into a scientific calculator, sometimes it's good to simply show an already created JPanel filled with the advance calculation buttons by using setVisible(true). If on the other hand you want to swap "views" of your GUI to reflect a substantial change in its state, for instance a word processor changing from edit mode to print mode, you could swap JPanels easily to do this using a CardLayout.

我将回答,有时这是有用的,例如,如果您想将标准计算器更改为科学计算器,有时最好只显示一个已经创建的、使用setVisible(true)填充了advance计算按钮的JPanel。另一方面,如果您想要交换GUI的“视图”,以反映GUI状态的重大变化,例如一个从编辑模式更改为打印模式的字处理器,您可以使用CardLayout轻松地交换jpanel。