3

I've been trying to figure out CardLayout with action listeners on button (so like - starts on a load-up page- and on a button click switches to a different "card"

my code won't even run right now i'm not entirely sure why - most implementations I can find use ItemListeners and Combo Boxes

The basic process I've done is create a master JPanel, but my cards JPanel onto the master JPanel, but my different cards into the cards JPanel, then add the master JPanel to the frame to display...

Also, for one of my cards I only need to display a picture - I previously implemented this by just creating a new pop-up window but It would be nice to be able to switch the frame to show it... I don't know why I can't figure this out

Here's my code:

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());
}

}
4

1 回答 1

3

问题:

  • 您的代码无法为我们编译,因为我们没有 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();
         }
      });
   }
}
于 2013-04-23T21:58:42.863 回答