带有自定义按钮的Java swing错误

带有自定义按钮的Java swing错误,java,image,swing,jar,jbutton,Java,Image,Swing,Jar,Jbutton,创建作为映像的自定义JButton时遇到问题。我用一个普通的JButton(如第二行的评论)处理一切,这样我就不必得到一个InputStream并启动一个带有图标的按钮。 我遇到的问题是,当我按下重播按钮(再次播放)时,窗口关闭,只会弹出一个窗口(正常的JButton就是这样),但在这种情况下,4-5个窗口会重新打开,我不知道为什么 我开始认为这是因为是时候获取一个InputStream并执行ImageIO.read()游戏将开始,并看到变量运行为false,然后开始重新打开窗口,直到它为tru

创建作为映像的自定义JButton时遇到问题。我用一个普通的JButton(如第二行的评论)处理一切,这样我就不必得到一个InputStream并启动一个带有图标的按钮。 我遇到的问题是,当我按下重播按钮(再次播放)时,窗口关闭,只会弹出一个窗口(正常的JButton就是这样),但在这种情况下,4-5个窗口会重新打开,我不知道为什么

我开始认为这是因为是时候获取一个
InputStream
并执行
ImageIO.read()
游戏将开始,并看到变量运行为false,然后开始重新打开窗口,直到它为true,但我不知道如何验证它

注意:我有一些函数可以在执行操作时验证蛇是否发生碰撞,如果发生碰撞,将调用
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个窗口将重新打开”


这表明您可能正在向replay JButton添加多个ActionListener。每次调用game over方法时都会添加一个新的侦听器,这是不正确的。我不会将ActionListener添加到game over方法中的按钮中,而是在创建replay按钮的地方添加一次。与完整程序(太大)或不可编译/不可运行的代码片段(您现在发布的代码片段)相比,代码帖子对我们(以及相应地对您)更有帮助。请考虑创建和张贴一个在你的问题。另请注意,通常最好将当前GUI重新设置为初始状态,而不是创建和显示新的GUI。这就解决了我的问题!但我还是不知道为什么会这样happens@AndréClérigo:同样,这是因为监听器被多次添加到按钮中。我不知道调用
gameOver()
的频率——只有您知道,因为只有您有正在运行的代码,但同样,每次调用它时,都会添加一个新的侦听器,这不会很好地工作。