Проблема здесь в три раза:
- Должен быть способ отображения фонового изображения.
- Нужно уметь найти точку, в которой была нажата мышь.
- Должен быть способ нарисовать точку на панели.
Одним из способов достижения указанных выше пунктов является подкласс JPanel
и предоставление этих функциональных возможностей.
1. Отображение фонового изображения на панели.
Во-первых, поскольку JPanel
не имеет способа отображения фонового изображения по умолчанию, должен быть способ удержать изображение в JPanel
, а затем нарисовать его на самой панели, что может быть выполняется методом paintComponent
.
Один из способов добиться этого - иметь в классе поле, которое содержит Image
для рисования:
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);
}
}
Объект Graphics
в paintComponent
связан с MyPanel
и может использоваться для выполнения графических операций.
2. Нахождение точки, в которой была нажата мышь.
Во-вторых, чтобы получить точку, в которой была нажата мышь, можно присвоить MouseListener
для MyPanel
. В следующем примере анонимный внутренний класс, расширяющий MouseAdapter
, используется для минимизации написания дополнительного кода:
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.
}
Обработка, которая должна выполняться при щелчке мыши, может быть включена в метод mouseClicked
.
3. Как нарисовать точку на панели.
В-третьих, чтобы найти точку, в которой была нажата мышь, ее можно получить из объекта MouseEvent
, переданного методом mouseClicked
:
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);
}
}
Хотя приведенный выше код не проверен, он должен быть отправной точкой.
Например, если нужно рисовать несколько точек, возможно, для хранения точек есть List<Point>
, и каждый Point
в методе paintComponents
может быть выполнен.
Если при щелчке мыши необходимо выполнить дополнительную обработку, можно добавить дополнительный код к методу mouseClicked
.
Дополнительные ресурсы:
Спасибо zedoo за указание в комментариях, что при переопределении метода paintComponent
следует выполнять вызов super.paintComponent
.