我正在构建一个带有画布的系统,用户可以通过在Java中拖动鼠标来绘制线条。我希望存储和显示所有笔画。但是,当我按下鼠标画一条新线时,前一行会被自动删除,这不是我所期待的。我该如何解决这个问题?
这是我的代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FreeDrawing extends JPanel implements MouseListener, MouseMotionListener {
private int indexOfStroke = 0;
private int indexOfPoint = 0;
private Stroke[] strokes = new Stroke[50];
private Point[] currentPoints = new Point[500];
public FreeDrawing(String name) {
super();
this.addMouseListener(this);
this.addMouseMotionListener(this);
JFrame fr = new JFrame(name);
fr.add(this);
fr.setSize(500, 500);
setBackground(Color.GRAY);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setVisible(true);
}
public void paintComponent(Graphics g) {
System.out.println("Paint");
super.paintComponents(g);
strokes[indexOfStroke] = new Stroke();
for (int i = 0; i < indexOfPoint - 1; i++) {
System.out.println("Really draw");
g.drawLine(currentPoints[i].x, currentPoints[i].y, currentPoints[i + 1].x, currentPoints[i + 1].y);
}
}
public void mouseDragged(MouseEvent e) {
System.out.println("Drag");
currentPoints[indexOfPoint] = new Point(e.getX(), e.getY());
indexOfPoint++;
repaint();
}
public void mousePressed(MouseEvent e) {
System.out.println("Press");
currentPoints[indexOfPoint] = new Point(e.getX(), e.getY());
indexOfPoint = 0;
repaint();
}
public void mouseReleased(MouseEvent e) {
indexOfPoint = 0;
indexOfStroke++;
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public static void main(String[] args) {
FreeDrawing canvas = new FreeDrawing("Mouse");
}
}
class Stroke {
public Stroke() {
System.out.println("Stroke initiated");
points = new Point[500];
}
Point[] points;
}
答案 0 :(得分:2)
因为,绘画是如何运作的,请参阅Painting in AWT and Swing和Performing Custom Painting了解更多详情。
基本上,绘画是破坏性的,这意味着每次调用paintComponent时,都需要从头开始重新绘制组件的整个状态
您可能会考虑做的一件事是创建一个类,其中包含每行所需的笔触,颜色和点,并在每次单击时将其存储在List中
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Drawing> drawings;
private Drawing current;
private Random rnd = new Random();
public TestPane() {
drawings = new ArrayList<>(25);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Stroke stroke = new BasicStroke(rnd.nextInt(9) + 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
Color color = new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255));
current = new Drawing(stroke, color);
current.addPoint(e.getPoint());
drawings.add(current);
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
current.addPoint(e.getPoint());
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawing drawing : drawings) {
drawing.paint(g2d);
}
g2d.dispose();
}
}
public class Drawing {
private Stroke stroke;
private Color color;
private List<Point> points;
public Drawing(Stroke stroke, Color color) {
this.stroke = stroke;
this.color = color;
this.points = new ArrayList<>(25);
}
public void addPoint(Point p) {
points.add(p);
}
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(color);
g2d.setStroke(stroke);
if (!points.isEmpty()) {
Point from = points.get(0);
for (Point to : points.subList(1, points.size())) {
g2d.draw(new Line2D.Double(from, to));
from = to;
}
}
g2d.dispose();
}
}
}