我的代码中有一个卡片布局错误,指出我在单击鼠标时遇到问题



我对卡片布局有问题。它指出(在GameWindow$2.mouseClicked(GameWindow.java:80((有一个错误。我的卡片布局如下所示

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

有人可以帮我解决问题吗?我有两个框架,一个包含游戏,另一个包含获取游戏阶段的按钮。有人可以为我做一件事吗? 对于卡片布局,布局为空

// 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) {
}

}

您已将布局设置为null-setLayout(null);,这相当于说getContentPane().setLayout(null)

观察。。。

  • 避免诸如startStage.setSize(getWidth(), getHeight()); // make the new JPanel fit the window之类的事情 - 让布局管理器完成它的工作
  • startStage.setVisible(true); // show the JPanel毫无意义,因为默认情况下 Swing 组件是可见
  • 避免从JFrame扩展。有很多原因(你的问题是一个亮点(,但你实际上并没有向类添加新的/可重用的功能,而是将自己锁定在一个用例中。 最好从JPanel开始,然后将其添加到您想要的任何容器中。
  • 不要使用KeyListener,请改用键绑定 API。 它将可靠地解决与KeyListener有关的所有问题
  • 我也会避免使用"组件"(如JLabel(作为游戏实体。按照定制的绘画路线,您将获得更好的运气和更大的灵活性

最新更新