从单独的 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
创建包含菜单 JButtons
的 JPanel
。登录 JPanel class 创建包含登录 Swing 组件的 JPanel
。
这是 JFrame
和菜单 JPanel
。
这是左键单击“登录”后的 GUI JButton
。
注意我是如何命名 classes 的。 CardPanel
、MenuPanel
、LoginPanel
。通过将 Panel 附加到 class 名称的末尾,这告诉我他们 use a JPanel
.
当我创建一个单独的 ActionListener
class 时,我会将其命名为 ButtonListener
或 SignupListener
.
我创建的唯一 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;
}
}
}
所以我想要一个 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
创建包含菜单 JButtons
的 JPanel
。登录 JPanel class 创建包含登录 Swing 组件的 JPanel
。
这是 JFrame
和菜单 JPanel
。
这是左键单击“登录”后的 GUI JButton
。
注意我是如何命名 classes 的。 CardPanel
、MenuPanel
、LoginPanel
。通过将 Panel 附加到 class 名称的末尾,这告诉我他们 use a JPanel
.
当我创建一个单独的 ActionListener
class 时,我会将其命名为 ButtonListener
或 SignupListener
.
我创建的唯一 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;
}
}
}