将另一个类中的JPanel添加到JFrame中的JPanel

9

我可以帮你进行翻译。以下是需要翻译的内容:

我无法从主类中获取我的JFrame以显示来自另一个类的JPanel。所有内容都能编译通过,没有错误。

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:

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);

    }

}

在不同类中保留不同的JPanels是否是一种好的实践?(例如:希望JFrame包含几个相同大小的JPanels,通过将setVisible()设置为true/false进行切换)
编辑:
感谢所有回答。注意到了。现在回到我的问题:
既然我知道如何添加在其他类中创建的单个GUI元素,我想知道是否可能使用布局管理器在其中一个类中组织元素(可能是JPanel之外的某个其他容器),这样我就可以将它们作为一个组在一个布局中添加(这就是我问关于在其他类中创建整个JPanel的原因)。就像图片上所示:
此示例中用于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");

    }

}

我在思考通过设置JPanel(例如示例中的一些)的可见或不可见来导航程序GUI。

  1. 这是一个好的方式吗?
  2. 我应该将GUI拆分成几个类,还是应该保持所有内容在一个类中?我这样问是因为现在只有代码中的一半GUI就已经有大约400行长了(目前只能“看”而不能做任何事情)。正如我之前所说 - 我是初学者,这是我迄今为止写过最长的应用程序之一(我肯定它并不那么长!)。

编辑

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

编辑

我查阅了Oracle的CardLayout教程,发现它对我的任务很有用(不包括从外部类创建JPanels,但这没关系)。我最初误解了它,并认为CardLayout仅限于选项卡窗格(我不想在我的项目中实现它)。


关于您最近的编辑,请查看我的回答中的修改。 - Hovercraft Full Of Eels
4个回答

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

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

它应该按照你的期望正常工作。


很好的发现!1个赞。原帖作者应该接受你的答案。 - Hovercraft Full Of Eels

6

首先回答您的问题,您需要在JFrameTest构造函数中添加类似以下代码的面板实例到框架中:

add(new JPanelOne());

您还需要直接将按钮添加到JPanelOne本身:
public class JPanelOne extends JPanel {   

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

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

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

    JPanel panelMain = new JPanel(mainLayout); 

每个容器都应该有自己的布局管理器实例。否则你的GUI会出现奇怪的问题:
setLayout(new FlowLayout());
JPanel panelMain = new JPanel(mainLayout);

有些布局管理器可以共享(我认为FlowLayout是其中之一),而有些则肯定不行(例如BoxLayout),但您的建议是有效的。 - Hovercraft Full Of Eels
@HovercraftFullOfEels 感谢您的澄清。我对共享布局管理器并不完全确定,它看起来有点靠不住。 - Code-Apprentice

5

在另一个网站上,我得到了用户“Hilek”的帮助,成功地将来自另一个类的JPanel显示在主类中。以下是代码:

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:

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);
        }
}

实例截图:

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

也许对于某些人的问题有帮助。


此代码无法执行。无法编译的源代码 - 错误的符号类型:javax.swing.JPanel.add - ParisaN

4
不要在JFrame上调用setSize()。相反,让布局设置其组件和GUI的适当大小。在将所有组件添加到GUI后,在JFrame上调用pack(),然后调用setVisble(true)。请注意,大多数布局尊重组件的preferredSize而不是其size。
另外,在单独的组件上调用setVisible(true)是不必要的(除非您在某种原因下在GUI运行后更改它们的可见性)。您还需要阅读有关使用布局管理器的更多信息,并且一旦您学习了它们,可能会较少使用FlowLayout。
关于您最近的编辑:
我会回答有时这很有帮助,例如,如果您想将标准计算器更改为科学计算器,有时候仅需使用setVisible(true)显示已经创建好的填充高级计算按钮的JPanel即可。另一方面,如果您想交换GUI的“视图”以反映其状态的实质性更改,例如,从编辑模式更改为打印模式的文字处理器,则可以轻松地交换JPanels来使用CardLayout完成此操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接