繁体   English   中英

将一个 JPanel 放到另一个来自不同 Java 类的 JPanel 上

[英]Put one JPanel onto another JPanel from a different Java class

我正在开发 Java Swing 应用程序。 我的应用程序有两个 Java 类。 class1.java ,我包括 JFrame、JButton 和 JPanel(panel1)。 当我单击按钮时,我想隐藏 panel1 并且应该显示 class2.java 的class2.java 我在 class1.java 的 button actionPerformed 方法中尝试了这个方法。 但它不起作用。

class2 pnl = new class2();     
this.remove(panel1);
this.add(pnl); 
this.validate();
this.repaint();

分析

您只希望JComponents显示在JFrame 我们可以通过使用单个JPanel来实现这一点,但在JButton的动作侦听器期间添加和删除JComponents

在不查看实际代码的情况下,最好采用可管理的方式来访问代码和实例化的对象。 下面列出的代码创建了一种很好且易于管理的方法。

实现这一目标

下面列出了整个类,并附有注释以供解释。

package swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

    public class MultiPaneledFrame {

        JFrame frame = new JFrame();
        JPanel window = new JPanel();

        // As you can see, we create an array containing all your JComponents.
        // We have two of these, to simulate multiple JPanel's.
        List<JComponent> window1Contents = new ArrayList<JComponent>();
        List<JComponent> window2Contents = new ArrayList<JComponent>();
        // NOTE: The above Lists can instead be stuck in their own class like asked for,
        // and instantiated on Class invocation.

        JButton goto2 = new JButton("Goto Panel 2");
        JButton goto1 = new JButton("Goto Panel 1");

        int panelToShow = 0; // 0 - First "panel".
                               // 1 - Second "panel".

        // Main method of class. Change 'Multi_Paneled_Frame' to the name of your Class.
        public MultiPaneledFrame() {
            // Execute anything else you want here, before we start the frame.
            window1Contents.add(goto2);
            window2Contents.add(goto1);

            // Here is where I personally am setting the coordinates of the JButton's on the JPanel.
            goto2.setPreferredSize(new Dimension(200, 100));
            goto1.setPreferredSize(new Dimension(200, 100));
            //goto2.setBounds(5, 5, 150, 30); < Used for 'null' layout.
            //goto1.setBounds(5, 5, 150, 30); < Used for 'null' layout.

            goto2.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addComponents(panelToShow = 1);
                }
            });
            goto1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    addComponents(panelToShow = 0);
                }
            });

            initialiseFrame();
        }

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new MultiPaneledFrame();
                }
            });
        }

        private void initialiseFrame() {
            frame.setSize(600, 400); // Change it accordingly.
            // Optional
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setResizable(false);
            // Needed
            frame.setVisible(true);
            frame.add(window);
            window.setLayout(new BorderLayout()); // Assuming your using a BorderLayout.
            //window.setLayout(null); < Uses 'null' layout.
            addComponents(panelToShow);

            // I always like to make sure that everything is on the frame nicely.
            frame.repaint();
            frame.validate();
        }

        private void addComponents(int panelNo) {
            if (panelNo == 0) {
                for (JComponent component : window1Contents) {
                    window.removeAll(); // We're removing everything that it contains and replacing it...
                    window.revalidate();
                    window.add(component, BorderLayout.CENTER);
                    //window.add(component); < Uses 'null' layout.
                    // Since we are using the first panel, we are adding
                    // everything from the first list of components to the window...
                }
            } else {
                for (JComponent component : window2Contents) {
                    window.removeAll(); // We're removing everything that it contains and replacing it...
                    window.revalidate();
                    window.add(component, BorderLayout.CENTER);
                    //window.add(component); < Uses 'null' layout.
                    // Since we are using the second panel, we are adding
                    // everything from the second list of components to the window...
                }
            }

            // Refreshes the frame.
            frame.repaint();
            frame.validate();
        }
    }

结论

虽然有无数种方法可以实现这样的目标,但我给出的方法是半有效的,而且非常灵活。 随意编辑代码,如果您有任何疑虑,或者提出问题,我将很乐意回答。

PS:此代码已在运行 OS X 10.11 和 Java 版本 8 更新 65 的 Macbook Air 上测试并运行。

CardLayout应该是您的解决方案。 在本教程中,他们展示了如何通过在 ComboBox 中选择一个值来从面板切换到另一个面板。

对 CarLayout 的一点解释:

CardLayout 允许您将不同的面板放在彼此的顶部,但一次只显示一个。 使用您的代码,您可以选择要显示的代码。

初始化:

this.setLayout(new CardLayout());

class1 pnl1 = new class1();
class2 pnl2 = new class2();

this.add(pnl1, "PANEL1");
this.add(pnl2, "PANEL2");

在您的按钮 actionPerformed 上:

CardLayout cl = (CardLayout)(this.getLayout());
cl.show(this, "PANEL2");

暂无
暂无

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

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