Making a game where you click a circle and a new one appears but can't figure out how to make the circle a button

Viewed 203

I'm quite new to JAVA and still learning and can't figure out how to make the location of my button iCirclePosX and iCirclePosY and make it shaped the same as the circle (The button redraws the circle) I'm fairly sure I have to use something other than BorderLayout but I don't know how it works and would like some assistance. Thanks!

package stackover;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import static java.lang.Math.random;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;

import so61997395.Board;
import so61997395.Circle;
import so61997395.Game;




/**
 *
 * @author 18086
 */

public class PaintFrame extends JFrame {
    public static int iCircleSize() {
        return (int)(Math.random() * 100 + 1);
    }

    public static int iCirclePosX() {
        return (int)(Math.random() * 750 + 1);
    }

    public static int iCirclePosY() {
        return (int)(Math.random() * 750 + 1);
    }

    private JPanel content = new JPanel();
    private JButton drawButton = new JButton("Draw");
    private PaintPanel paintPanel = new PaintPanel();

    public PaintFrame() {
        getContentPane().add(content);
        content.setLayout(new BorderLayout());

        drawButton.setSize(100, 500);
        drawButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // drawButton is fired, repaint the paintPanel
                paintPanel.repaint();
            }
        });
        content.add(drawButton, BorderLayout.WEST);
        content.add(paintPanel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        new PaintFrame().start();
    }

    public void start() {
        int iSize = iCircleSize();
        PaintPanel board = new PaintPanel();
        board.add(new Circle(iCirclePosX(), iCirclePosY(), new 
            Dimension(iSize+100, iSize+100)));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(800, 800);
        frame.setContentPane(board);
        frame.setVisible(true);
    }
}


class PaintPanel extends JPanel {
    PaintPanel() {
        super(null);
    }

    public void PaintPanel() {
        setSize(750, 750);
        setBackground(Color.PINK);
    }
}   

class Circle extends JComponent {

    Circle(int x, int y, Dimension size) {
        setBounds(new Rectangle(new Point(x, y), size));
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                paintPanel.repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.YELLOW); 

        // draw 5 random circles 
        int count = 1;
        PaintPanel repaintPanel = new PaintPanel();
        for (int i = 0; i < count; i++) {
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }

}
1 Answers

To have a clickable circle

One possibility will be to create a subclass of Jbutton and override the paint method to draw a circle. But that will lead to many other issues.

Another one will be to maintains a collection of all drawn circles and listen for the mouse click on the container panel to see if the mouse was clicked on a button.

Yet anther solution (the one that I will choose) would be to create a custom component that paint the circle and listen for mouse click.

To position your circles

The best layout will be null. With a null layout you have an absolute layout where components are positioned according to their bounds : https://docs.oracle.com/javase/tutorial/uiswing/layout/none.html


Edit; Add sample code

package so61997395;

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

public class Game {

    public static void main(String[] args) {
        new Game().start();
    }

    public void start() {
        Board board = new Board();
        board.add(new Circle(150, 80, new Dimension(30, 30)));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setContentPane(board);
        frame.setVisible(true);
    }
}

class Board extends JPanel {
    Board() {
        super(null);
    }
}

class Circle extends JComponent {
   Circle(int x, int y, Dimension size) {
        setBounds(new Rectangle(new Point(x, y), size));
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                move();
            }
        });
    }

    private void move() {
        Container board = SwingUtilities.getAncestorOfClass(JPanel.class, this);
        setLocation(new Point(
                ThreadLocalRandom.current().nextInt(board.getWidth()),
                ThreadLocalRandom.current().nextInt(board.getHeight())
        ));
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(Color.RED);
        g.fillOval(0, 0, getWidth(), getHeight());
    }
}
Related