I have a Java paint program that uses a custom JPanel to paint on. While when clicking on the JPanel paints a small oval (or circle, if you will), the oval disappears each time you click on another place. The coordinates also get updated, but the oval does not stay, it moves to wherever the user clicks next... Here's the code for the custom JPanel:
int xCord, yCord;
public class PaintPanel extends JPanel implements MouseListener {
// default serial whatever...
private static final long serialVersionUID = -6514297510194472060L;
// initial values
int xCord = -10;
int yCord = -10;
public PaintPanel() {
addMouseListener(this);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(ProgramUI.currentColor);
g.fillOval(xCord, yCord, 8, 8);
repaint();
}
@Override
public void mouseClicked(MouseEvent m) {
}
@Override
public void mouseEntered(MouseEvent m) {
}
@Override
public void mouseExited(MouseEvent m) {
}
@Override
public void mousePressed(MouseEvent m) {
if (paintPanel.contains(m.getPoint())) {
xCord = m.getX();
yCord = m.getY();
System.out.println("x: " + xCord + " y: " + yCord);
}
}
@Override
public void mouseReleased(MouseEvent m) {
}
}
I need the holding of a mouse to continuously paint an oval until the mouse button is let go. The only problem here is that the mouse oval updates, but does not save it's original position. How do I fix this?
Only one oval is drawn as there is only one fillOval
statement drawing a single oval in the paintComponent
method so the statement
super.paintComponent(g);
causes any previous painting to be cleared once repaint
is called.
To paint multiple ovals, you can paint components from a List<Point>
as outlined in Custom Painting Approaches
Don't call repaint
from within paintComponent
. This creates an infinite loop and degrades performance. If periodic updates are required invoke repaint
from the ActionListener
of a Swing Timer instead.
这是因为组件会重新绘制自身,以使更改永久生效,因此,每次完成绘制后,都应该拍摄jpanel的图像并将其设置为背景...
You are only painting the last place the user clicked each time. Instead, you need to collect the past clicks and paint them all each time.
This code will do what you want:
package com.sandbox;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
public class SwingSandbox {
public static void main(String[] args) {
JFrame frame = buildFrame();
frame.add(new PaintPanel());
}
public static class PaintPanel extends JPanel implements MouseListener {
// default serial whatever...
private static final long serialVersionUID = -6514297510194472060L;
ArrayList<Point> points = new ArrayList<Point>();
public PaintPanel() {
addMouseListener(this);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(250));
for (Point point : points) {
g.fillOval(point.x, point.y, 8, 8);
}
repaint();
}
@Override
public void mouseClicked(MouseEvent m) {
}
@Override
public void mouseEntered(MouseEvent m) {
}
@Override
public void mouseExited(MouseEvent m) {
}
@Override
public void mousePressed(MouseEvent m) {
if (this.contains(m.getPoint())) {
points.add(m.getPoint());
}
}
@Override
public void mouseReleased(MouseEvent m) {
}
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
return frame;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.