Java 带有自定义按钮的摆动错误
Java swing bug with custom button
在创建作为图像的自定义 JButton 时遇到问题。我让一切都与普通的 JButton 一起工作(就像在第二行的评论中一样)这样我就不必获得 InputStream 并启动按钮有一个图标。
我遇到的问题是当我按下重播按钮(再次播放)时 window 关闭并且只有一个 window 应该弹出(就像“普通”JButton 发生的那样)但是在这个案例 4-5 windows 重新打开,我不知道为什么。
我开始认为这是因为获得 InputStream
并执行 ImageIO.read()
的时间,游戏将开始并看到变量 运行 为 false 然后开始重新打开 windows 直到它是真的,但我不知道如何验证它。
注意: 我有一些函数可以在 ActionPerformed 上验证蛇是否发生碰撞,如果是,running = false
和 GameOver()
将被调用
public class GamePanel extends JPanel implements ActionListener {
JButton replay; //= new JButton("Play Again");
GamePanel() {
...
try {
InputStream is_replay = this.getClass().getResourceAsStream("/Snake/lib/img/playagain.png");
ImageIcon icon = new ImageIcon(ImageIO.read(is_replay));
replay = new JButton(icon);
replay.setBorder(BorderFactory.createEmptyBorder());
replay.setContentAreaFilled(false);
...
} catch (IOException|FontFormatException e) {
e.printStackTrace();
}
this.add(replay);
replay.setVisible(false);
replay.setBounds(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT - 200, 200, 100);
...
startGame();
}
public void startGame() {
spawnApple();
running = true;
timer = new Timer(DELAY, this);
timer.start();
}
public void gameOver(Graphics g) {
...
replay.setVisible(true);
replay.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == replay) {
JComponent comp = (JComponent)e.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
win.dispose(); //It will close the current window
new GameFrame(); //It will create a new game
}
}
});
}
}
public class GameFrame extends JFrame {
GameFrame() {
JPanel panel = new GamePanel();
this.add(panel);
panel.setLayout(null); //Needed to add components
this.setTitle("Snake Game");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.pack(); //Fit JFrame to the components
this.setVisible(true);
this.setLocationRelativeTo(null);
}
}
public class SnakeGame {
public static void main(String[] args) throws Exception {
new GameFrame();
}
}
"在这种情况下 4-5 windows 重新打开"
这表明您可能正在向重播 JButton 添加多个 ActionListener。每次调用 game over 方法时都会添加一个新的侦听器,这是不正确的。我不会将 ActionListener 添加到游戏结束方法中的按钮,而是将其添加 一次 在您创建重播按钮的位置。
在创建作为图像的自定义 JButton 时遇到问题。我让一切都与普通的 JButton 一起工作(就像在第二行的评论中一样)这样我就不必获得 InputStream 并启动按钮有一个图标。 我遇到的问题是当我按下重播按钮(再次播放)时 window 关闭并且只有一个 window 应该弹出(就像“普通”JButton 发生的那样)但是在这个案例 4-5 windows 重新打开,我不知道为什么。
我开始认为这是因为获得 InputStream
并执行 ImageIO.read()
的时间,游戏将开始并看到变量 运行 为 false 然后开始重新打开 windows 直到它是真的,但我不知道如何验证它。
注意: 我有一些函数可以在 ActionPerformed 上验证蛇是否发生碰撞,如果是,running = false
和 GameOver()
将被调用
public class GamePanel extends JPanel implements ActionListener {
JButton replay; //= new JButton("Play Again");
GamePanel() {
...
try {
InputStream is_replay = this.getClass().getResourceAsStream("/Snake/lib/img/playagain.png");
ImageIcon icon = new ImageIcon(ImageIO.read(is_replay));
replay = new JButton(icon);
replay.setBorder(BorderFactory.createEmptyBorder());
replay.setContentAreaFilled(false);
...
} catch (IOException|FontFormatException e) {
e.printStackTrace();
}
this.add(replay);
replay.setVisible(false);
replay.setBounds(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT - 200, 200, 100);
...
startGame();
}
public void startGame() {
spawnApple();
running = true;
timer = new Timer(DELAY, this);
timer.start();
}
public void gameOver(Graphics g) {
...
replay.setVisible(true);
replay.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == replay) {
JComponent comp = (JComponent)e.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
win.dispose(); //It will close the current window
new GameFrame(); //It will create a new game
}
}
});
}
}
public class GameFrame extends JFrame {
GameFrame() {
JPanel panel = new GamePanel();
this.add(panel);
panel.setLayout(null); //Needed to add components
this.setTitle("Snake Game");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.pack(); //Fit JFrame to the components
this.setVisible(true);
this.setLocationRelativeTo(null);
}
}
public class SnakeGame {
public static void main(String[] args) throws Exception {
new GameFrame();
}
}
"在这种情况下 4-5 windows 重新打开"
这表明您可能正在向重播 JButton 添加多个 ActionListener。每次调用 game over 方法时都会添加一个新的侦听器,这是不正确的。我不会将 ActionListener 添加到游戏结束方法中的按钮,而是将其添加 一次 在您创建重播按钮的位置。