如何在java中有效地使用cardlayout,以便使用各种面板构造函数内的按钮从面板切换

我是新手使用cardlayout,我有一些关于如何实现它的问题。 我首先想知道实现cardlayout的最佳方法,以便我可以从面板切换到面板。 我的主要问题是如何使用面板构造器内的按钮从面板切换到面板。 我今天刚刚开始研究这个项目,所以你会看到一些未完成或没有意义的代码。 我首先尝试使我的所有类扩展JFrame,但这导致了多个不需要的窗口。 如果我能得到一些关于如何有效使用cardlayout以及如何使用我的其他面板构造器中的按钮切换面板的示例。 我尝试使用cardlayout只适用于我在gui类中创建的按钮,但这不是我想要的结果。 如果可以,请提供帮助,并提前致谢。

这是我的主要课程。

public class controller{ public static void main(String[] args){ new Gui(); } } 

这是我的gui课。

 import java.awt.CardLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Gui extends JFrame{ homePage home = new homePage(); public JPanel loginPanel = new textEmailLog(), registerPanel = new Register(), homePanel = new homePage(), viewPanel = new emailView(), loadPanel = new loadEmail(), contentPanel = new JPanel(new CardLayout()); CardLayout cardLayout = new CardLayout(); public Gui(){ super("Email Database Program"); setSize(700,700); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); contentPanel.setLayout(cardLayout); contentPanel.add(loginPanel, "Login"); contentPanel.add(registerPanel, "Register"); contentPanel.add(homePanel, "Home"); contentPanel.add(viewPanel, "View"); contentPanel.add(loadPanel, "Load"); this.setContentPane(contentPanel); cardLayout.show(contentPanel, "Login"); setVisible(true); } 

我的登录面板类

 import java.awt.CardLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; //panel has been added public class textEmailLog extends JPanel{ JPanel logGui = null; JButton registerBut, logBut; JTextField Login; public textEmailLog(){ //default characteristics setSize(700,700); setName("Email Database"); //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Labels for username and password JLabel userLab = new JLabel("Username"); JLabel pwLab = new JLabel("Password"); //textfields for username and password Login = new JTextField("", 15); JPasswordField Password = new JPasswordField("", 15); Password.setEchoChar('*'); //login button that confirms username and password logBut = new JButton("Login"); logBut.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub //needs regex checks prior to logging in if(e.getSource() == logBut){ /* Change the panel to the homepage if(Login.getText().equals() && Password.getText().equals()){ } */ new homePage(); } } }); registerBut = new JButton("Register"); registerBut.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == registerBut){ //Change the panel to the register panel } } }); //Box layout for organization of jcomponents Box verticalContainer = Box.createVerticalBox(); Box horizontalContainer = Box.createHorizontalBox(); Box mergerContainer = Box.createVerticalBox(); //add to panel verticalContainer.add(Box.createVerticalStrut(300));//begin relative to the center verticalContainer.add(userLab);//Login label and text verticalContainer.add(Login); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(pwLab);//password label and text verticalContainer.add(Password); verticalContainer.add(Box.createVerticalStrut(5)); horizontalContainer.add(registerBut);//register button horizontalContainer.add(Box.createHorizontalStrut(5)); horizontalContainer.add(logBut);//login button //combines both the vertical and horizontal container mergerContainer.add(verticalContainer); mergerContainer.add(horizontalContainer); add(mergerContainer); //this.add(logGui); setVisible(true); } 

}

我的注册面板类

  import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; //No Panel addition public class Register extends JPanel{ JButton submit, previous; JLabel firstLab, lastLab, userLab, passwordLab, repassLab, address, emailAdd, errorLabel; JTextField firstText, lastText, userText, addText, emailAddText; JPasswordField passwordText, repassText; public Register(){ setSize(700,700); //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //register values and their labels and textfields firstLab = new JLabel("First Name: "); firstText = new JTextField("", 25); lastLab = new JLabel("Last Name: "); lastText = new JTextField("", 40); userLab = new JLabel("Username: "); userText = new JTextField("", 25); passwordLab = new JLabel("Password: "); passwordText = new JPasswordField("", 25); passwordText.setEchoChar('*'); repassLab = new JLabel("Confirm Password"); repassText = new JPasswordField("", 25); repassText.setEchoChar('*'); address = new JLabel("Address: "); addText = new JTextField("", 50); emailAdd = new JLabel("Email Address: "); emailAddText = new JTextField("", 50); //error message for reigstration issues errorLabel = new JLabel(); errorLabel.setForeground(Color.red); submit = new JButton("Submit"); submit.addActionListener(new ActionListener(){ @SuppressWarnings("deprecation") public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == submit){ //confirm with regex methods and if statements that have been created and need to be created if(firstText.getText().length() == 0){ errorLabel.setText("*You have not entered a first name!"); }else if(lastText.getText().length() == 0){ errorLabel.setText("*You have not entered a last name!"); }else if(userText.getText().length() == 0){ errorLabel.setText("*You have not entered a username!"); }else if(passwordText.toString().length() == 0){ errorLabel.setText("*You have not entered a Password!"); }else if(repassText.toString().length() == 0){ errorLabel.setText("*You have not matched your password!"); } if(addText.getText().length() == 0){ errorLabel.setText("*You have not entered an address!"); }else if(emailAddText.getText().length() == 0){ errorLabel.setText("*You have not entered an Email address!"); }else if(userText.getText().length() < 8){ errorLabel.setText("*Username is too short!"); } else if(!(passwordText.toString().matches(repassText.toString()))){ errorLabel.setText("Passwords do not match!"); } else if(!isValidEmailAddress(emailAddText.getText())){ errorLabel.setText("*Invalid Email!"); } else if(!isValidAddress(addText.getText())){ errorLabel.setText("*Invalid Address!"); } } } }); //returns to the previous page previous = new JButton("Previous Page"); previous.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == previous){ //card.show(login panel); } } }); Box verticalContainer = Box.createVerticalBox(); Box horizontalContainer = Box.createHorizontalBox(); Box mergerContainer = Box.createVerticalBox(); verticalContainer.add(Box.createVerticalStrut(150)); verticalContainer.add(firstLab); verticalContainer.add(firstText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(lastLab); verticalContainer.add(lastText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(userLab); verticalContainer.add(userText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(passwordLab); verticalContainer.add(passwordText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(repassLab); verticalContainer.add(repassText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(address); verticalContainer.add(addText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(emailAdd); verticalContainer.add(emailAddText); verticalContainer.add(Box.createVerticalStrut(5)); //horizontal verticalContainer.add(Box.createVerticalStrut(5)); horizontalContainer.add(submit); horizontalContainer.add(Box.createHorizontalStrut(5)); horizontalContainer.add(previous); //merger mergerContainer.add(verticalContainer); mergerContainer.add(horizontalContainer); add(mergerContainer); setVisible(true); } //regex check for valid Email public boolean isValidEmailAddress(String email){ java.util.regex.Pattern p = java.util.regex.Pattern.compile("[A-Za-z0-9._\\%-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"); java.util.regex.Matcher m = p.matcher(email); return m.matches(); } //regex check for valid Address public boolean isValidAddress(String address){ java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\d{1,3}.?\\d{0,3}\\s[a-zA-Z]{2,30}\\s[a-zA-Z]{2,15}"); java.util.regex.Matcher m = p.matcher(address); return m.matches(); } } 

主页面板类

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; //NO Panel Yet @SuppressWarnings("serial") public class homePage extends JPanel{ JButton uploadEmail, viewEmail; public homePage(){ setSize(700,700); uploadEmail = new JButton("Upload Your Email"); uploadEmail.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == uploadEmail){ new loadEmail(); } } }); viewEmail = new JButton("View An Email"); viewEmail.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == viewEmail){ new emailView(); } } }); add(uploadEmail); add(viewEmail); setVisible(true); } } 

我的查看电子邮件面板

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JTextField; public class emailView extends JPanel{ JPanel viewPanel; JButton logout, delete, homepage; JTable emailList; //Cannot be edited or may be in a new panel /* JLabel fileLab, toLab, fromLab, subjectLab,topicLab, emailLab, notesLab, attachLab; JTextField fileText, toText, fromText, subjectText, topicText; JTextArea emailText, notesText, attachText; */ public emailView(){ setSize(700,700); setVisible(true); emailList = new JTable(); logout = new JButton("Logout"); logout.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == logout){ new textEmailLog(); } } }); delete = new JButton("Delete"); delete.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == delete){ } } }); homepage = new JButton("HomePage"); homepage.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == homepage){ new homePage(); } } }); Box horizontalContainer = Box.createHorizontalBox(); Box verticalContainer = Box.createVerticalBox(); Box mergerContainer = Box.createVerticalBox(); horizontalContainer.add(logout); horizontalContainer.add(Box.createHorizontalStrut(5)); horizontalContainer.add(homepage); horizontalContainer.add(Box.createHorizontalStrut(5)); horizontalContainer.add(delete); horizontalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(emailList); mergerContainer.add(horizontalContainer); mergerContainer.add(verticalContainer); add(mergerContainer); setVisible(true); } } 

我上传电子邮件面板

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; public class loadEmail extends JPanel{ JPanel loadPanel; JLabel fileLab, toLab, fromLab, subjectLab, topicLab, emailLab, notesLab, attachLab; JTextField fileText, toText, fromText, subjectText, topicText; JTextArea emailText, notesText, attachText; //attachment text will be changed JButton cancel, complete, enter;//enter may not be necessary public loadEmail(){ setSize(700,700); fileLab = new JLabel("Enter a new File: "); fileText = new JTextField(); enter = new JButton("Enter"); enter.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == enter){ //opens file directory window } } }); toLab = new JLabel("To: "); toText = new JTextField(); toText.setSize(5, 30); fromLab = new JLabel("From: "); fromText = new JTextField(); subjectLab = new JLabel("Subject: "); subjectText = new JTextField(); topicLab = new JLabel("Topic: "); topicText = new JTextField(); emailLab = new JLabel("Email Content: "); emailText = new JTextArea(); notesLab = new JLabel("Comments: "); notesText = new JTextArea(); attachLab = new JLabel("Attachments"); attachText = new JTextArea(); cancel = new JButton("Cancel"); cancel.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == cancel){ //dispose page } } }); complete = new JButton("Complete"); complete.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource() == complete){ //store in database, prompt user for new email to enter in other wise return to homepage } } }); Box verticalContainer = Box.createVerticalBox(); Box horizontalContainer = Box.createHorizontalBox(); Box mergerContainer = Box.createVerticalBox(); verticalContainer.add(fileLab); verticalContainer.add(fileText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(Box.createHorizontalStrut(50)); verticalContainer.add(enter); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(toLab); verticalContainer.add(toText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(fromLab); verticalContainer.add(fromText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(subjectLab); verticalContainer.add(subjectText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(topicLab); verticalContainer.add(topicText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(emailLab); verticalContainer.add(emailText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(notesLab); verticalContainer.add(notesText); verticalContainer.add(Box.createVerticalStrut(5)); verticalContainer.add(attachLab); verticalContainer.add(attachText); verticalContainer.add(Box.createVerticalStrut(5)); horizontalContainer.add(cancel); horizontalContainer.add(Box.createHorizontalStrut(5)); horizontalContainer.add(complete); mergerContainer.add(verticalContainer); mergerContainer.add(horizontalContainer); add(mergerContainer); setVisible(true); } } 

简短的回答是不。 原因是您必须将父容器和CardLayout暴露给所有子组件,这不仅会使您的应用程序的某些部分暴露于潜在的error handling,它会使导航紧密耦合,从而难以添加/删除未来…

一个更好的解决方案是设计某种控制器interface ,它定义每个视图可以做什么(例如showHomenextViewpreviousView ),然后你将这个接口的实现传递给每个视图。 然后,每个视图将使用此接口根据需要请求更改。

控制器将根据需要知道诸如当前视图,主视图以及如何在某些视图(下一个/上一个)之间移动之类的事情。

更新了简单的示例

 import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Component; import java.awt.Container; import java.awt.EventQueue; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class AllYouViewBelongToMe { public static void main(String[] args) { new AllYouViewBelongToMe(); } public AllYouViewBelongToMe() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public interface ViewContoller { public void goHome(); public void nextView(); public void previousView(); } public static class DefaultViewController implements ViewContoller { public static final String HOME = "home"; private Component currentView = null; private List views; private Map mapNames; private Container parent; private CardLayout cardLayout; public DefaultViewController(Container parent, CardLayout cardLayout) { this.parent = parent; this.cardLayout = cardLayout; views = new ArrayList<>(25); mapNames = new HashMap<>(25); } public CardLayout getCardLayout() { return cardLayout; } public Container getParent() { return parent; } public void addView(Component comp, String name) { if (!HOME.equals(name)) { views.add(comp); } mapNames.put(comp, name); getParent().add(comp, name); } public void removeView(Component comp, String name) { views.remove(comp); mapNames.remove(comp); getParent().remove(comp); } @Override public void goHome() { currentView = null; getCardLayout().show(getParent(), HOME); } @Override public void nextView() { if (views.size() > 0) { String name = null; if (currentView == null) { currentView = views.get(0); name = mapNames.get(currentView); } else { int index = views.indexOf(currentView); index++; if (index >= views.size()) { index = 0; } currentView = views.get(index); name = mapNames.get(currentView); } getCardLayout().show(getParent(), name); } } @Override public void previousView() { if (views.size() > 0) { String name = null; if (currentView == null) { currentView = views.get(views.size() - 1); name = mapNames.get(currentView); } else { int index = views.indexOf(currentView); index--; if (index < 0) { index = views.size() - 1; } currentView = views.get(index); name = mapNames.get(currentView); } getCardLayout().show(getParent(), name); } } } public class TestPane extends JPanel { public TestPane() { setLayout(new BorderLayout()); CardLayout cardLayout = new CardLayout(); JPanel view = new JPanel(cardLayout); final DefaultViewController controller = new DefaultViewController(view, cardLayout); controller.addView(createPane("home"), DefaultViewController.HOME); controller.addView(createPane("Page #1"), "View1"); controller.addView(createPane("Page #2"), "View2"); controller.addView(createPane("Page #3"), "View3"); controller.addView(createPane("Page #4"), "View4"); controller.goHome(); JPanel controls = new JPanel(); JButton btnPrev = new JButton("<"); JButton btnHome = new JButton("Home"); JButton btnNext = new JButton(">"); controls.add(btnPrev); controls.add(btnHome); controls.add(btnNext); btnNext.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.nextView(); } }); btnPrev.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.previousView(); } }); btnHome.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.goHome(); } }); add(view); add(controls, BorderLayout.SOUTH); } protected JPanel createPane(String name) { JPanel panel = new JPanel(new GridBagLayout()); panel.add(new JLabel(name)); return panel; } } }