【问题标题】:CardLayout (swing) with action listeners on buttons?CardLayout(swing)在按钮上带有动作侦听器?
【发布时间】:2013-04-17 06:46:44
【问题描述】:

我一直在尝试通过按钮上的动作侦听器找出 CardLayout (就像 - 从加载页面开始 - 并在按钮上单击切换到不同的“卡片”

我的代码现在甚至无法运行我不完全确定为什么 - 我能找到的大多数实现都使用 ItemListeners 和 Combo Boxes

我做的基本流程是创建一个master JPanel,但是我的卡片JPanel放到master JPanel上,但是我不同的卡片放到cards JPanel中,然后把master JPanel添加到frame中显示...

另外,对于我的一张卡片,我只需要显示一张图片 - 我之前通过创建一个新的弹出窗口来实现这一点,但是能够切换框架以显示它会很好......我不知道为什么我想不通

这是我的代码:

import java.awt.*;

/** 
 * Game
 * Main class that specifies the frame and widgets of the GUI
 */
public class Game implements Runnable {
public void run(){

    final String ON_OPEN = "Welcome!"; //Opening frame
    final String GAME = "Play!"; // Game Frame
    final String STATS = "Stats"; // Post-Game Stat Frame
    final String HELP = "Help"; //tutorial frame
    JPanel cards = new JPanel(); 
    JPanel master; // a panel for the card layout

    final JFrame frame = new JFrame(ON_OPEN);
    frame.setLocation(500,200);

    //Create the master layout for the program
    master = (JPanel) frame.getContentPane();
    master.setLayout(new BorderLayout()); // creating master layout

    //Create panel for all the cards in CardLayout
    final CardLayout cLay = new CardLayout();
    cards.setLayout(cLay);


    // all the cards
    final JPanel help = new JPanel();
    final JPanel stats = new JPanel();
    final JPanel game = new JPanel (new BorderLayout());
    final JPanel open = new JPanel (new FlowLayout());


    // setting up ON_OPEN layout - uses JPanel open

    final ImageIcon img = new ImageIcon("Instructions.png", "My Instructions..."); // the image I want shown under HELP card
    final JButton info = new JButton("Help");
    info.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
    //      cLay.show(help, HELP);     // WHAT I NORMALLY SHOULD BE DOING, RATHER JUST MAKE A NEW FRAME FOR THIS THOUGH
    //      frame.pack();

            final JFrame infoFrame = new JFrame("Tutorial");
            infoFrame.setLocation(500,50);
            JLabel tutorialImg = new JLabel(img);
    //      int w = img.getIconWidth();
        //  int h = img.getIconHeight();
            //infoFrame.setSize(w, h);
            infoFrame.pack();
            infoFrame.add(tutorialImg);
            infoFrame.setVisible(true);
        }
    });
    open.add(info); // the open-tutorial button



    //Add them to the cards JPanel
    cards.add(open, ON_OPEN);
    cards.add(help, HELP);
    cards.add(stats, STATS);
    cards.add(game, GAME);

    //Add the cards panel to the Master layout panel
    master.add(cards);


    // This code is all commented out because I'm not sure what I'm doing here...
//  frame.add(cards);
//  cLay.show(cards, ON_OPEN);

//  frame.add(open, BorderLayout.CENTER);

    // Main playing area - I want this to be shown in the GAME card...

    GridLayout tileGrid = new GridLayout(4,4);
    final JPanel grid = new JPanel(tileGrid);
      //    game.add(grid, BorderLayout.CENTER);

    //      grid.setLayout(tileGrid);
    //  frame.add(grid, BorderLayout.CENTER);


    // Input - holds typing box
    //        final JPanel status_panel = new JPanel();

    //  frame.add(cards, BorderLayout.CENTER);


//  frame.add(open, BorderLayout.CENTER);

    final JTextField typingArea = new JTextField();
    typingArea.setFocusTraversalKeysEnabled(false);
    typingArea.setEditable(true);
    typingArea.setFocusable(true);
    typingArea.requestFocus();


    frame.add(typingArea, BorderLayout.SOUTH);
    typingArea.addKeyListener(new KeyAdapter() {
        public void keyPressed (KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) { // enter key is pressed
                String userWord = typingArea.getText().toLowerCase();
                typingArea.setText("");

            }
        }
    });


    final JLabel status = new JLabel("Running...");
    //        status_panel.add(status);

    // Reset button
    final JPanel control_panel = new JPanel();
    frame.add(control_panel, BorderLayout.NORTH);



    ]

    // Put the frame on the screen
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}


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

}

【问题讨论】:

    标签: java swing jframe jbutton cardlayout


    【解决方案1】:

    问题:

    • 您的代码无法为我们编译,因为我们没有 JLetterField 类。
    • 您正在尝试将 JFrame 的 contentPane 添加回自身,并导致异常且没有意义。

    编辑 1:

    • 您的最新代码显示您将所有内容都放入一个非常大的 run() 方法中,但这样做,您失去了很多,却一无所获。
    • 我建议去掉 Runnable 接口,不需要它,并创建一个真正符合 OOP 的类,该类具有私有字段以及公共和私有方法。
    • 您的 actionPerformed 方法显示未尝试更改 CardLayout 的显示卡片。
    • 我建议你去掉显示新窗口的代码,并尝试在那里放置换卡代码。
    • 制作您的 CardLayout 和该类的卡片显示 JPanel 字段,以便其他方法可以访问它们并调用它们的方法。

    编辑 2:

    例如,以下代码显示了使用 3 个 JButton 交换卡片。一张获得上一张卡片,一张获得下一张卡片,一张展示如何获得一张特定卡片(这里是第二张):

    import java.awt.BorderLayout;
    import java.awt.CardLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class CardLayoutEg extends JPanel {
       private static final String[] CARD_LABELS = { "one", "two", "three", "four",
             "five", "six", "seven", "eight", "nine", "ten" };
       private static final int PREF_W = 400;
       private static final int PREF_H = PREF_W;
       private CardLayout cardlayout = new CardLayout();
       private JPanel cardHolder = new JPanel(cardlayout);
       private Action[] actions = { new ShowPreviousAction(), new ShowNextAction(),
             new ShowTwoCardAction() };
    
       public CardLayoutEg() {
          for (String cardLabelText : CARD_LABELS) {
             JLabel cardLabel = new JLabel(cardLabelText, SwingConstants.CENTER);
             cardHolder.add(cardLabel, cardLabelText);
          }
    
          JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
          for (Action action : actions) {
             btnPanel.add(new JButton(action));
          }
    
          setLayout(new BorderLayout());
          add(cardHolder, BorderLayout.CENTER);
          add(btnPanel, BorderLayout.SOUTH);
       }
    
       @Override
       public Dimension getPreferredSize() {
          return new Dimension(PREF_W, PREF_H);
       }
    
       private class ShowPreviousAction extends AbstractAction {
          public ShowPreviousAction() {
             super("Previous");
          }
    
          @Override
          public void actionPerformed(ActionEvent e) {
             cardlayout.previous(cardHolder);
          }
       }
    
       private class ShowNextAction extends AbstractAction {
          public ShowNextAction() {
             super("Next");
          }
    
          @Override
          public void actionPerformed(ActionEvent e) {
             cardlayout.next(cardHolder);
          }
       }
    
       private class ShowTwoCardAction extends AbstractAction {
          public ShowTwoCardAction() {
             super("Show Two");
          }
    
          @Override
          public void actionPerformed(ActionEvent e) {
             cardlayout.show(cardHolder, CARD_LABELS[1]);
          }
       }
    
       private static void createAndShowGui() {
          CardLayoutEg mainPanel = new CardLayoutEg();
    
          JFrame frame = new JFrame("CardLayout Example");
          frame.setDefaultCloseOperation(JFrame.EXIT_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();
             }
          });
       }
    }
    

    【讨论】:

    • 添加了 JLetterField 类 - 我在哪里尝试将 contentPane 添加回自身,我在哪里说 frame.add(master, BorderLayout.CENTER) ?我正在努力做到这一点,以便在打开仅有的两个按钮时,您可以看到“信息”按钮,上面写着“帮助”并更改布局以显示“Instructions.png”图片 - 然后在该按钮下有一个按钮标有“Play”(我还没有制作)的标签会将布局更改为“GAME”卡..
    • @user2310306:为了论坛的目的,不要给我们这个类,你应该只使用一个 JTextField。该类与您手头的问题无关,因此您的工作是简化您的代码,以便它仍然可以编译但显示您的问题。请现在就这样做。关于contentPane,主JPanel JFrame 的contentPane。再说一次,你为什么要把它加回来?没有意义。它已经在那里了!我建议你放弃上面的代码,尝试用最简单的代码解决手头的问题。
    • 已编辑.. 感谢我对 java 很陌生,感谢您耐心等待这个网站
    • @user2310306:请参阅第二次编辑以回答示例代码。请同时阅读 CardLayout 教程。
    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 2023-03-30
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    相关资源
    最近更新 更多