TheAnonymous010
TheAnonymous010

Reputation: 725

Placing a restart button on my screen

I have created a "Game Over!" page when the user loses in my game. Under g.drawString(...), I am trying to create a button that the user can click to restart the game. I am having trouble getting a button to appear and stay visible.

How can I create a JButton in a custom paint(Graphics g) method in Java? Any suggestions?

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

public class Game extends JPanel implements KeyListener {

    private Player player;
    private Stage stage;
    private Stage stageLeft;
    private Stage stageRight;
    private EnemyManager manager;

    private boolean isGameOver = false;
    private boolean restart = false;

    public Game() {
        setSize(800,600);
        setPreferredSize(new Dimension(800,600));
        setFocusable(true);
        setBackground(Color.WHITE);
        requestFocus();
        addKeyListener(this);

        stage = new Stage(0, 540, 800, 100);
        stageLeft = new Stage(-1, 0, 1, 600);
        stageRight = new Stage(800, 0, 1, 600);
        player = new Player(this, 400, 400);
        manager = new EnemyManager(this, 10);
    }

    @Override
    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0,0,getWidth(),getHeight());

        stage.draw(g);
        stageLeft.draw(g);
        stageRight.draw(g);
        if(!isGameOver || restart) {
            player.draw(g);
            manager.draw(g);
        } else {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());

            g.setColor(Color.WHITE);
            g.setFont(new Font("Century Gothic", Font.BOLD, 24));
            g.drawString("Game Over!", 330, 275);

            g.drawRect(330, 300, 145, 40);
            g.drawString("Restart", 350, 320);

            //TODO: Make a restart button that works
        }

        g.dispose();
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int c = e.getKeyCode();
        if(c == KeyEvent.VK_W) {

        }
        if(c == KeyEvent.VK_A) {
            player.setxDir(-1);
        }
        if(c == KeyEvent.VK_S) {

        }
        if(c == KeyEvent.VK_D) {
            player.setxDir(1);
        }
    }

    public void setGameOver(boolean flag) {
        isGameOver = flag;
    }

    @Override
    public void keyReleased(KeyEvent e) {
        player.setxDir(0);
        player.setyDir(0);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    public Stage getStage() {
        return stage;
    }

    public Stage getStageLeft() { return stageLeft; }

    public Stage getStageRight() { return stageRight; }

    public EnemyManager getEnemyManager() {
        return manager;
    }

    public static void main(String[] args) {

        Game game = new Game();

        JFrame frame = new JFrame();
        frame.setTitle("Java Game");
        frame.add(game);
        frame.pack();
        frame.setPreferredSize(new Dimension(800,600));
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Center window
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Upvotes: 1

Views: 192

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Regarding,

How can I create a JButton in a custom paint(Graphics g) method in java?

Answer: you don't. Never create or place components within any of the painting methods. These methods are for rendering images and rendering only and should never be used for component creation or program logic.

This question is an XY Problem:

I have created a "Game Over!" page when the user loses in my game. Under g.drawString(...), I am trying to create a button that the user can click to restart the game. I am having trouble getting a button to appear and stay visible.

In that you're asking for a solution to a specific code problem, when the true best solution is to use a different approach. I suggest:

  • Create a JPanel that displays your background image in its paintComponent method, not its paint method as per the Swing painting tutorials
  • Add your JButton to this JPanel as you would add it to any JPanel, and not in its painting methods.
  • You're better off creating a separate JPanel to do this, and then swap JPanels when needed via a CardLayout.

Other issues:

  • Never dispose of a Graphics object given to you by the JVM. Doing this breaks the painting chain.
  • You should almost always call the super's painting method inside of your override so that the painting chain can continue. So if you override paintComponent as per my recommendation, you should be sure to call the super.paintComponent(g) method within your own override.
  • Never call repaint() from within a painting method. This is a very bad way to try to do animation as it is uncontrollable and risky.
  • Don't override update() as while this is done for AWT painting, it is not generally used for Swing graphics or animation.

Upvotes: 2

Related Questions