The issue here is three-fold:
- There needs to be a way to display a background image.
- One must be able to find the point at which the mouse was clicked.
- There must be a way to draw the point on the panel.
One way to accomplish the above points would be to subclass a JPanel
and provide those functionalities.
1. Display a background image in a panel.
Firstly, as a JPanel
does not have a way of displaying a background image by default, there must be a way to hold an image in the JPanel
, and then draw that on the panel itself, which can be performed via the paintComponent
method.
One way to accomplish this is to have a field in the class which holds on to an Image
to draw:
class MyPanel extends JPanel {
// Background image. Initialize appropriately.
Image backgroundImage;
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw background image each time the panel is repainted.
g.drawImage(backgroundImage, 0, 0, null);
}
}
The Graphics
object in paintComponent
is associated with the MyPanel
and can be used to perform graphics operations.
2. Finding the point at which the mouse was clicked.
Secondly, in order to retrieve the point at which the mouse was clicked, one could assign a MouseListener
to the MyPanel
. In the following example, an anonymous inner class extending the MouseAdapter
is used to minimize writing extra code:
class MyPanel extends JPanel {
// Background image. Initialize appropriately.
Image backgroundImage;
public MyPanel() {
// Add a MouseListener which processes mouse clicks.
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
// Process mouse-click.
}
})
}
// paintComponents method here.
}
Processing that needs to be performed when the mouse is clicked can be included in the mouseClicked
method.
3. How to draw a point on the panel.
Thirdly, in order to find one point at which the mouse was clicked, one can obtain it from the MouseEvent
object that was passed in from the mouseClicked
method:
class MyPanel extends JPanel {
// Background image. Initialize appropriately.
Image backgroundImage;
Point pointClicked;
public MyPanel() {
// Add a MouseListener which processes mouse clicks.
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
// Retrieve the point at which the mouse was clicked.
pointClicked = e.getPoint();
// Repaint the panel.
this.repaint();
}
})
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw background image each time the panel is repainted.
g.drawImage(backgroundImage, 0, 0, null);
// Draw a little square at where the mouse was clicked.
g.fillRect(pointClicked.x, pointClicked.y, 1, 1);
}
}
Although the above code is not tested, it should be a starting point.
For example, if multiple points needs to be drawing, perhaps having a List<Point>
to hold the points, and drawing each Point
in the paintComponents
method could be done.
If additional processing needs to be performed when the mouse is clicked, additional code can be added to the mouseClicked
method.
Additional resources:
Thank you to zedoo for pointing out in the comments that making a call to super.paintComponent
should be performed when overriding the paintComponent
method.