I am quite new to Java and Swing, and this is also my first post so sorry if it doesn't make too much sense.
What I am trying to do is when I click on a JPanel, I want it to add a circle where I click. At the moment, all that seems to happen is when I click, a small grey square appears inside the JPanel I want to add to, but I can't seem to find any way of making it draw as a circle.
I have a class that extends JPanel called "Ball" which is what is being added when I click. At the moment, I am not too worried about it being in the correct location, just for it to draw the ball correctly. Below is the code for my "Ball" class:
package paintsliders;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
class Ball extends JPanel{
private int x,y,w,h;
//I will use this constructor to put the ball in the correct location later.
Ball(){
/*this.w = 100;
this.h = 100;
this.x = 200;
this.y = 200;*/
}
//draw the ball
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(200,200,10,10);
g.setColor(Color.RED);
}
}
I can kind of guess that it is something to do with the paintComponent method, but everywhere I have looked doesn't seem to have a solution for me.
Any help would be great, thanks!
The Graphcis
context has already been translated to meet the x/y location that the component should appear within it's parent container, this means that the top, left corner of the Graphics
context within the paintComponent
method is actually 0x0.
You need to define some size for the ball, you're painting at 10x10, which would suggest that your ball component should return a preferredSize
of 10x10
public Dimension getPreferredSize() {
return new Dimension(10, 10);
}
You will become responsible for providing appropriate layout details to the ball when it's added to the parent container...
public void mouseClicked(MouseEvent evt) {
Point p = evt.getPoint();
Ball ball = new Ball();
Dimension size = ball.getPreferredSize();
ball.setBounds(new Rectangle(p, size));
add(ball);
}
This, of course, assumes you have a null
layout set for the parent container
UPDATED
Something like...
public class PaintBalls {
public static void main(String[] args) {
new PaintBalls();
}
public PaintBalls() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Board());
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Board() {
setLayout(null);
setBackground(Color.WHITE);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
Ball ball = new Ball();
Dimension size = ball.getPreferredSize();
p.x -= size.width / 2;
p.y -= size.height / 2;
ball.setBounds(new Rectangle(p, size));
add(ball);
repaint();
}
});
}
}
public class Ball extends JPanel {
public Ball() {
setOpaque(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(10, 10);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.fillOval(0, 0, 10, 10);
g2d.dispose();
}
}
}
You probably have a main JPanel
where you click.
I would rather design the main panel to handle the mouse click and the Ball
class to be a simple Object
that defines a drawBall(Graphics g, int x, int y)
method that knows how to paint a Ball
. This would be called by the paintComponent()
method in the main panel. In the main panel, you handle the mouse click, create an object of type Ball
and call repaint()
. Inside the paintComponent()
you call ball.drawBall()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With