从单独的 class 访问 JPanel 组件

Accessing JPanel components from a seperate class

所以我想要一个 CardLayout class 在菜单页面和主应用程序页面之间切换,但我想在它们自己的 classes 中设计这两个面板,然后添加一个ActionListener 和 CardLayout 在不同的 class 中,并让 ActionListener 使用在其中一个面板中创建的按钮 classes.

这是一个(不那么短的)SSCCE,涵盖了我想说的内容:

import java.awt.*;
import javax.swing.*;

public class MenuPanel extends Frame{
    JPanel menuPanel;
    JButton login;
    JButton signup;

    public MenuPanel(){
        menuPanel = new JPanel(new GridBagLayout());
        login = new JButton("Login");
        signup = new JButton("Signup");
        
        menuPanel.add(login);
        menuPanel.add(signup);
        
    }
}
import java.awt.*;
import javax.swing.*;

public class MainPanel extends JFrame{
    JPanel menuPanel;
    JButton login;
    JButton signup;

    public MainPanel(){
        mainPanel = new JPanel(new GridBagLayout());=
        
        menuPanel.setBackground(Color.grey);
        
    }
}
import java.awt.*;
import javax.swing.*;

public class CardLayout extends Frame implements ActionL {
//Now how do I add the frames from the other classes so that I can add them to my CardLayout?
CardLayout cl = new CardLayout();
JPanel panelCont;
    public CardLayout() {
        frame.add(panelCont);

        panelCont = new JPanel(cl);
        //Here is where I'm having trouble
        panelCont.add(menuPanel, "1");
        panelCont.add(mainPanel, "2");

        cl.show(panelCont, "1");

        login.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                cl.show(panelCont, "2");
            }
        });
    }
}

public class Main {
    public static void main(String[] args) {
        new CardLayout();
    }
}

您不能将 Frame 添加到另一个组件。 Frame 是具有本机对等体的顶级组件。您应该从其他东西(JPanel?)中 subclass 而不是

此外,顺便说一句,您所做的设计不是很好。通常,在 MVC Swing 设计中,所有视图和控件方面应该在一个 class 中。不要将视图拆分为多个 classes,除非每个 classes 都作为自己的可重用小部件

Oracle 有一个有用的教程,Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay close attention to the Concurrency in Swing and the Laying Out Components Within a Container 个部分。

在 Java Swing 中,您可以创建一个 JFrame 以及创建 GUI 所需的多个 JPanels

我在三个不同的 class 中创建了一张卡片 JPanel、一个菜单 JPanel 和一个登录 JPanel。卡片 JPanel class 用 CardLayout 创建 JPanel。菜单 JPanel 创建包含菜单 JButtonsJPanel。登录 JPanel class 创建包含登录 Swing 组件的 JPanel

这是 JFrame 和菜单 JPanel

这是左键单击“登录”后的 GUI JButton

注意我是如何命名 classes 的。 CardPanelMenuPanelLoginPanel。通过将 Panel 附加到 class 名称的末尾,这告诉我他们 use a JPanel.

当我创建一个单独的 ActionListener class 时,我会将其命名为 ButtonListenerSignupListener.

我创建的唯一 ActionListener 将菜单​​登录名 JButton 与显示登录名 JPanel 联系起来。由于它由一行组成,因此我使用 lambda 表达式将其设为匿名 class。

这是完整的可运行代码。我将所有额外的 classes 都放在 classes 中,这样我就可以 post 将这段代码作为一个块。您可以而且应该将这些 class 放在单独的文件中。

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class CardLayoutExample implements Runnable {

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

    @Override
    public void run() {
        JFrame frame = new JFrame("CardLayout Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(new CardPanel().getPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    public class CardPanel {
        
        private final CardLayout cardLayout;
        
        private final JPanel panel;
        
        public CardPanel() {
            this.cardLayout = new CardLayout();
            this.panel = createCardPanel();
        }
        
        private JPanel createCardPanel() {
            JPanel panel = new JPanel(cardLayout);
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            
            panel.add(new MenuPanel(this).getPanel(), "menu");
            panel.add(new LoginPanel().getPanel(), "login");
            
            return panel;
        }
        
        public void showLoginPanel() {
            cardLayout.show(panel, "login");
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }
    
    public class MenuPanel {
        
        private final CardPanel cardPanel;
        
        private final JPanel panel;
        
        public MenuPanel(CardPanel cardPanel) {
            this.cardPanel = cardPanel;
            this.panel = createMenuPanel();
        }
        
        private JPanel createMenuPanel() {
            JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            
            JButton login = new JButton("Login");
            login.addActionListener(event -> cardPanel.showLoginPanel());
            panel.add(login);
            
            JButton signup = new JButton("Signup");
            panel.add(signup);
            
            return panel;
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }
    
    public class LoginPanel {
        
        private final JPanel panel;
        
        private final JPasswordField passwordField;
        
        private final JTextField useridField;
        
        public LoginPanel() {
            this.useridField = new JTextField(30);
            this.passwordField = new JPasswordField(30);
            this.panel = createLoginPanel();
        }
        
        private JPanel createLoginPanel() {
            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.LINE_START;
            gbc.fill = GridBagConstraints.NONE;
            gbc.insets = new Insets(5, 5, 5, 5);
            gbc.gridwidth = 1;
            
            gbc.gridx = 0;
            gbc.gridy = 0;
            JLabel label = new JLabel("Userid:");
            panel.add(label, gbc);
            
            gbc.gridx++;
            panel.add(useridField, gbc);
            
            gbc.gridx = 0;
            gbc.gridy++;
            label = new JLabel("Password:");
            panel.add(label, gbc);
            
            gbc.gridx++;
            panel.add(passwordField, gbc);
            
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridwidth = 2;
            gbc.gridx = 0;
            gbc.gridy++;
            JButton button = new JButton("Submit");
            panel.add(button, gbc);
            
            return panel;
        }
        
        public String getUserid() {
            return useridField.getText();
        }
        
        public char[] getPassword() {
            return passwordField.getPassword();
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }

}