... in an image and do some calculation on their [x y] coordinates.
My first idea was to use an image as the background of a JPanel and then register the points, but I'm not sure there will be a way to mark these on the JPanel. There is also the Drawing library, which I'm unfamiliar with, but I'm not sure if I can combine these with Swing.
Can you name me the packages/classes I can use in order to do the task? References of code that already does it are also welcome.
Thank you!
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:
- Lesson: Performing Custom Painting
- Painting in AWT and Swing
- How to Write a Mouse Listener
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.
Subclass a JPanel and override the method paintComponent:
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
In the method you can use methods of the Graphics object passed to it. This method will be invoked every time there is a need to redraw the panel, so you need to store your points in an array and then read and draw each of them in your paintComponent.
You may also find this useful, in case you want a heavyweight component (AWT), this tutorial explains how to extend the Canvas class to draw stuff.
The Background Panel gives a couple of suggestion on how to display a background image depending on your requirements.
Custom Painting Approaches then gives some ideas of how to do custom painting if you need to add custom points to the image.