简体   繁体   中英

Java swing bug with custom button

Having problems creating a custom JButton that is an Image. I had everything working with a normal JButton (like in the comment on the 2nd line) this way I wouldn't have to get an InputStream and start the button has an icon. The trouble I'm having is that when I pressed the replay button (to play again) the window closes and only one window should pop out (as it happens with a "normal" JButton) but in this case 4-5 windows reopen and I don't know why.

I started thinking it was because the time to get an InputStream and doing ImageIO.read() the game would start and see that the variable running was false and then started reopening windows until it's true but I can't see how to verify that.

Note: I have functions that on ActionPerformed verify if the snake has collided and if so running = false and GameOver() will be called

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

"in this case 4-5 windows reopen"

This suggests that you are probably adding multiple ActionListeners to the replay JButton. A new listener is added each time game over method is called, and this is incorrect. I would not add the ActionListener to the button in the game over method but rather add it once where you create the replay button.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM