Let's say I have two classes, the first extends JPanel and using Graphics draws a playing board on it. The second makes a JFrame and adds the panel to it.
You can imagine the frame looking something like this:
I now want to add an ellipse to a specific rectangle on click. I understand that I would be using a two-dimensional array in order to get the position I wanted, but I don't understand how the ellipse itself would be drawn on to the existing panel since I used the paint(Graphics g)
to draw the playing board.
Here is the code for drawing the board itself if you need it:
class MyBoard extends JPanel {
private static int height = 6;
private static int width = 7;
private static int squareSize = 100;
private int board[][] = new int[height][width];
public void paint(Graphics g) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
g.drawRect(j * squareSize, i * squareSize, squareSize, squareSize);
}
}
}
}
Thanks!
First two things that you should remember: Never override paint
but paintComponent
and call super.paintComponent
in there so that borders and everything works as expected. Regarding why this is the case, reference this question: Difference between paint() and paintcomponent()?
Now to answer your question. Assuming you have an existing logic to determine in which square you want to draw your Ellipse (let's assume you have two Integer
s elX
and elY
that are the column and row of your square) you can simply go and draw it after you have finished drawing the board itself.
Imagine sample code like this:
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Draw the board
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
g.drawRect(j * squareSize, i * squareSize, squareSize, squareSize);
}
}
// Draw the ellipse at the correct location using half the size of a normal square.
g.drawOval(elX * squareSize + squareSize / 4, elY * squareSize + squareSize / 4, squareSize / 2 , squareSize / 2);
}
Now the final part of how to go about actually determining where to draw your ellipse.
A simple solution would be to add a MouseListener
to your panel. And then in the mouseClicked
method you calculate where you actually did click.
Could look like this:
this.addMouseListener(new MouseListener()
{
@Override
public void mouseClicked(MouseEvent e)
{
int column = e.getX() / squareSize;
int row = e.getY() / squareSize;
board[column][row] = 1;
}
[...] // add the other methods to override
}
Then you slightly adapt your paintComponent
method with something like this:
for (int column = 0; column < width; ++column)
{
for (int row = 0; row < height; ++row)
{
if (board[column][row] == 1)
{
g.drawOval(column * squareSize + squareSize / 4, row * squareSize + squareSize / 4, squareSize / 2, squareSize / 2);
}
}
}
and now you draw an ellipse everywhere you click. You could also check if the clicked square already has 1
set as a value and reset it to 0
to have some toggle mechanism or increment it and draw different things based on the integer value... it's all up to you :)