-1

I have an issue with the card layout. It sates that (at GameWindow$2.mouseClicked(GameWindow.java:80)) There's an error. My card layout looks like this

                ((CardLayout) getContentPane().getLayout()).show(getContentPane(), "game");

Can someone please help me figure the issue out. I have two frames one that contains the game and the other contains the button to get the game stage. Can someone please do this one thing for me. The layout is Null for the card layout

// Import necessary GUI classes
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JLabel;
import javax.swing.Timer;

// "Extend" the JFrame class so we can customize it but still keep all its features
public class GameWindow extends JFrame implements ActionListener, KeyListener {

    // Serial version UIDs are used to differentiate between different object
    // versions--don't worry about it!
    private static final long serialVersionUID = 1L;

    JLabel Player = new JLabel();
    int playerSpeed = 1;
    int FPS = 30;
    // The keys set holds the keys being pressed
    private final Set<Integer> keys = new HashSet<>();

    // This main method runs when the program is executed
    public static void main(String[] args) {

        // This method runs a new "runnable" program after a brief pause that allows the
        // main program to exit
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                // The try/catch block prevents errors from crashing the program
                try {
                    GameWindow window = new GameWindow(); // Create and setup the main game window
                    window.setVisible(true); // show the new window
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Constructor: runs when a GameWindow object is created (instantiated)
     */
    public GameWindow() {

        // Run the parent class constructor
        super();
        // Allow the panel to get focus
        setFocusable(true);
        // Don't let keys change the focus
        setFocusTraversalKeysEnabled(false);

        setBounds(100, 100, 250, 360); // the window will appear at (100, 100) and 250w by 260h
        setTitle("Banana Jumper 1.0"); // the window will have this title
        setResizable(false); // the window can't be resized
        setLocationRelativeTo(null); // the window will move to the centre of the screen
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when the window is closed, the program will exit
        getContentPane().setLayout(new CardLayout()); // the window can swap between "stages" added as JPanels

        // Make a new screen with a button and put it in the window
        JPanel startStage = new JPanel(); // Create a new JPanel and add it to the card layout
        startStage.setSize(getWidth(), getHeight()); // make the new JPanel fit the window
        startStage.setBackground(Color.BLUE); // set the JPanel background to blue
        JButton playButton = new JButton("Play"); // Add a button to the panel
        playButton.addMouseListener(new MouseAdapter() { // Set the button to switch to the game stage
            @Override
            public void mouseClicked(MouseEvent arg0) {
                ((CardLayout) getContentPane().getLayout()).show(getContentPane(), "game");
                setLayout(null);
            }
        });
        startStage.add(playButton); // add the button to the stage
        add(startStage, "start"); // add the stage to the window


        // Create a second JPanel with band add it to the card layout
        JPanel gameStage = new JPanel();
        gameStage.setSize(getWidth(), getHeight());
        gameStage.setVisible(true);
        gameStage.setBackground(Color.RED);
        // Add a button to the panel
        JButton mainButton = new JButton("Back to Main Menu");
        // Set the button to switch to the start stage
        mainButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                ((CardLayout) getContentPane().getLayout()).show(getContentPane(), "start");
            }
        });
        gameStage.add(mainButton);
        // Put the stages in the window
        add(startStage, "start");
        add(gameStage, "game"); // put the stage in the window


        // Setup the movable box
         Player.setBounds(10, 10, 10, 10);
         Player.setVisible(true);
         Player.setBackground(Color.BLUE);
         // Opaque makes the background visible
         Player.setOpaque(true);

         // Setup the key listener
         addKeyListener(this);
         // Null layout allows moving objects!!!
         setLayout(null);
         add(Player);

         // Set the timer
         Timer tm = new Timer(1000 / FPS, this);
         tm.start();

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
     // Move up if W is pressed
     if (keys.contains(KeyEvent.VK_W)) {
      Player.setLocation(Player.getX(), Player.getY() - playerSpeed);
     }
     // Move right if D is pressed
     if (keys.contains(KeyEvent.VK_D)) {
      Player.setLocation(Player.getX() + playerSpeed, Player.getY());
     }
     // Move down if S is pressed
     if (keys.contains(KeyEvent.VK_S)) {
      Player.setLocation(Player.getX(), Player.getY() + playerSpeed);
     }
     // Move left if A is pressed
     if (keys.contains(KeyEvent.VK_A)) {
      Player.setLocation(Player.getX() - playerSpeed, Player.getY());
     }
    }

    @Override
    public void keyPressed(KeyEvent e) {
     // Add the key to the list
     // of pressed keys
     if (!keys.contains(e.getKeyCode())) {
      keys.add(e.getKeyCode());
     }
    }

    @Override
    public void keyReleased(KeyEvent e) {
     // Remove the key from the
     // list of pressed keys
     keys.remove((Integer) e.getKeyCode());
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }


}

1 Answers1

0

You've set the layout to null - setLayout(null);, which is the equivalent of saying getContentPane().setLayout(null)

Observations...

  • Avoid things like startStage.setSize(getWidth(), getHeight()); // make the new JPanel fit the window - let the layout manager do it's job
  • startStage.setVisible(true); // show the JPanel is pointless, as Swing components are visible by default
  • Avoid extending from JFrame. Theres lots of reasons (your problem is a highlight of one), but you're not actually adding a new/re-usable functionality to the class and you're locking your self into a single use case. Better to start with a JPanel and add it to what ever container you want.
  • Don't use KeyListener, use the Key Bindings API instead. It will solve all the issues related to KeyListener, reliably
  • I would also avoid using "components" (like JLabel) as a game entity. You will have better luck and greater flexibility following a custom painting route
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366