在JFrame中实现CardLayout并根据特定按钮切换卡片

我在下面发布了我的代码。 我有一个简单的任务,即创建一个可导航的GUI。 我花了几个小时研究如何完成这个,这就是我把它放在一起的代码。

最初我想要在没有任何布局或任何东西的情况下执行导航。 在用户点击欢迎面板上的“登录”按钮后,我需要显示主面板。

它显示欢迎卡就好了,但是当我到达validateLogin方法时(按下登录按钮时激活,并且成功登录后它应该显示卡中的主页面板)它只是保留在欢迎面板上,即使我已validation我的程序到达循环以通过system.out.Println()更改卡

请帮忙。 我整个星期六都试图通过试验和研究解决这个问题,但没有成功。 这对我来说是最后的手段,所以如果有人能告诉我我的缺点,那么我很乐意继续前进并修复它。 然后将该修复应用于我的程序所需的许多其他卡。

enter code here public class mainGUI implements ActionListener{ JFrame main; JPanel cards = new JPanel(new CardLayout()); CardLayout cl = (CardLayout)(cards.getLayout()); //Items for the welcome panel JPanel welcome = welcomePanel(); JButton login; JButton register; JTextField username; JTextField password; //home panel JPanel home = homePanel(); //WelcomePanel welcome = new WelcomePanel(); ArrayList students = new ArrayList(); Student workingStudent; /** * calls load() at start and save() on exit * */ public mainGUI(){ load(); main = new JFrame(); main.setSize(900, 600); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); main.setTitle("MyCourses 2k16"); main.setContentPane(welcomePanel()); //fill out the cards cards.add(welcome, "Welcome"); cards.add(home, "Home"); //display welcome card cl.show(cards, "welcome"); main.setVisible(true); saveState(); } private JPanel welcomePanel() { JPanel welcome = new JPanel(); welcome.setLayout(null); welcome.setBackground(Color.DARK_GRAY); JLabel hi = new JLabel("Welcome to MyCourses 2K16"); hi.setSize(800, 100); hi.setLocation(50,50); hi.setFont(new Font("Serif", Font.BOLD, 48)); hi.setForeground(Color.WHITE); JLabel select = new JLabel("Fill in the information, then click login or register to proceed, no special characters allowed"); select.setSize(700,100); select.setLocation(75,100); select.setFont(new Font("Serif", Font.PLAIN, 18)); select.setForeground(Color.WHITE); login = new JButton( "login"); login.setSize(100, 50); login.setLocation(50, 200); login.addActionListener(this); register = new JButton( "register"); register.setSize(100,50); register.setLocation(200, 200); register.addActionListener(this); JLabel un = new JLabel("username"); un.setSize(100, 30); un.setLocation(50, 270); un.setForeground(Color.WHITE); username = new JTextField(); username.setSize(200, 30); username.setLocation(50,300); JLabel pw = new JLabel("password"); pw.setSize(100, 30); pw.setLocation(50, 350); pw.setForeground(Color.WHITE); password = new JTextField(); password.setSize(200, 30); password.setLocation(50,380); welcome.add(hi); welcome.add(select); welcome.add(login); welcome.add(register); welcome.add(un); welcome.add(username); welcome.add(pw); welcome.add(password); return welcome; } private JPanel homePanel() { JPanel home = new JPanel(); home.setLayout(null); home.setBackground(Color.DARK_GRAY); JLabel hi = new JLabel("HOME"); hi.setSize(800, 100); hi.setLocation(50,50); hi.setFont(new Font("Serif", Font.BOLD, 48)); hi.setForeground(Color.WHITE); return home; } public void load(){ } private void saveState(){ Iterator it = students.iterator(); while(it.hasNext()){ it.next().saveStudent(); } } public static void main(String[] args) { new mainGUI(); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource()==login){ System.out.println("Logging in..."); validateLogin(students); } else if (e.getSource()==register){ } } private void validateLogin(ArrayList students){ boolean valid = false; for(int i = 0; i < students.size(); i++){ if(username.getText().equals(students.get(i).getUsername()) && password.getText().equals(students.get(i).getPassword())) { valid = true; workingStudent=(students.get(i)); System.out.println("Successful Login!"); cl.show(cards, "home"); } } if(valid == false){ System.out.println("Invalid Login, try again"); } } 

}

你创建了一个使用CardLayout,卡片的JPanel,但你把它添加到任何东西,所以它当然不会显示自己,也不会显示它的卡片。 解决方案:将此JPanel添加到GUI。

所以代替:

 main.setContentPane(welcomePanel()); 

做:

 main.setContentPane(cards); 

问题2:

使用字符串作为键类型时使用字符串常量。 请注意,您将一个JPanel添加到卡JPanel:

 cards.add(home, "Home"); 

但是然后尝试显示它:

 cl.show(cards, "home"); 

但是Home和家里不一样。

而是声明一个常量,HOME:

 public static final String HOME = "home"; 

并使用相同的常量来添加JPanel并显示它。

举个简单的例子:

 import java.awt.CardLayout; import java.awt.event.ActionEvent; import javax.swing.*; public class MainGui2 extends JPanel { private CardLayout cardLayout = new CardLayout(); private WelcomePanel welcomePanel = new WelcomePanel(this); private HomePanel homePanel = new HomePanel(); public MainGui2() { setLayout(cardLayout); add(welcomePanel, WelcomePanel.NAME); add(homePanel, HomePanel.NAME); } public void showCard(String name) { cardLayout.show(this, name); } private static void createAndShowGui() { MainGui2 mainPanel = new MainGui2(); JFrame frame = new JFrame("MainGui2"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } class WelcomePanel extends JPanel { public static final String NAME = "welcome panel"; private MainGui2 mainGui2; public WelcomePanel(final MainGui2 mainGui2) { this.mainGui2 = mainGui2; add(new JLabel(NAME)); add(new JButton(new AbstractAction("Logon") { @Override public void actionPerformed(ActionEvent e) { mainGui2.showCard(HomePanel.NAME); } })); } } class HomePanel extends JPanel { public static final String NAME = "home panel"; public HomePanel() { add(new JLabel(NAME)); } }