单程:
- 使用 ArrayList 在绘制当前曲线时绘制它,但是
- 使用 BufferedImage 绘制完成的曲线
- 您可以在 mouseReleased 上执行此操作,并使用当前颜色将当前曲线绘制到 BufferedImage。
- 在绘制到 BufferedImage 后,您还需要重新初始化点的 ArrayList。
- 使用完 BufferedImage 的 Graphics 对象后,不要忘记将其丢弃。
- 在 super.paintComponent 之后但在绘制当前曲线之前,在 PaintComponent 方法中绘制 BufferedImage。
- 这样,当您更改绘图的颜色时,只有当前曲线受到影响。
EDIT
您在评论中提到您不熟悉 BufferedImage,并且正在寻找另一种方法。我想您可以创建一个类,其中包含点的 ArrayList 和颜色,然后在每个 mouseReleased 上创建该类的一个对象,并将其添加到绘图面板中的 ArrayList 中。然后你的paintComponent方法可以迭代该ArrayList,绘制具有相关颜色的点列表,但我的直觉告诉我,你是一个聪明的人,你很快就会学会如何使用BufferedImage。我真的认为这是最好的解决方案。如果您尝试但失败了,请向我们展示您的代码,我们很可能会为您提供帮助。
EDIT 2
BufferedImage 构造函数需要图像宽度、高度和图像类型——我对此并不 100% 熟悉。我通常使用 BufferedImage.TYPE_INT_RGB 进行通用绘图,并使用 BufferedImage.TYPE_INT_ARGB 进行通用,也需要 alpha。然后,如果您需要的是 Graphics 对象而不是 Graphics2D 对象,则将从 BufferedImage 中提取 Graphics 对象,例如 getGraphics()。然后,当您在构造函数中初始化 BufferedImage 时,用 Color.white 填充它,就像您在 JPanel 中一样。然后处理 Graphics 对象。然后每次要绘制的时候,就获取Graphics,用它进行绘制,就像在paintComponent方法中所做的那样,完成后将Graphics处理掉,最后通过drawImage方法在paintComponent中绘制BufferedImage。
EDIT 3
示例程序并没有完全完成您想要做的事情,但确实说明了 BufferedImage 与绘图的使用。每次绘制新路径或曲线时,该程序都会更改颜色。
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;
public class STTestSimple {
private static void createAndShowUI() {
STDrawPanel drawPanel = new STDrawPanel();
STMouseAdapter mAdapter = new STMouseAdapter(drawPanel);
drawPanel.addMouseListener(mAdapter);
drawPanel.addMouseMotionListener(mAdapter);
JFrame frame = new JFrame("Drawing");
frame.getContentPane().add(drawPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
@SuppressWarnings("serial")
class STDrawPanel extends JPanel {
private static final int ST_WIDTH = 700;
private static final int ST_HEIGHT = 500;
private static final Color BACKGROUND_COLOR = Color.white;
private static final float STROKE_WIDTH = 6f;
private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
private static final Color[] colors = {Color.black, Color.blue, Color.red,
Color.green, Color.orange, Color.MAGENTA};
private BufferedImage bImage = new BufferedImage(ST_WIDTH, ST_HEIGHT,
BufferedImage.TYPE_INT_RGB);
private Color color = Color.black;
private ArrayList<Point> points = new ArrayList<Point>();
private int colorIndex = 0;
public STDrawPanel() {
Graphics g = bImage.getGraphics();
g.setColor(BACKGROUND_COLOR);
g.fillRect(0, 0, ST_WIDTH, ST_HEIGHT);
g.dispose();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bImage, 0, 0, null);
Graphics2D g2 = (Graphics2D) g;
drawCurve(g2);
}
private void addCurveToBufferedImage() {
Graphics2D g2 = bImage.createGraphics();
drawCurve(g2);
g2.dispose();
}
private void drawCurve(Graphics2D g2) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(STROKE);
g2.setColor(color);
if (points != null && points.size() > 1) {
for (int i = 0; i < points.size() - 1; i++) {
int x1 = points.get(i).x;
int y1 = points.get(i).y;
int x2 = points.get(i + 1).x;
int y2 = points.get(i + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(ST_WIDTH, ST_HEIGHT);
}
public void curveStart(Point point) {
points.clear();
points.add(point);
}
public void curveEnd(Point point) {
points.add(point);
addCurveToBufferedImage();
points.clear();
repaint();
colorIndex++;
colorIndex %= colors.length;
setColor(colors[colorIndex]);
}
public void curveAdd(Point point) {
points.add(point);
repaint();
}
public void setColor(Color color) {
this.color = color;
}
}
class STMouseAdapter extends MouseAdapter {
private STDrawPanel drawPanel;
public STMouseAdapter(STDrawPanel drawPanel) {
this.drawPanel = drawPanel;
}
@Override
public void mousePressed(MouseEvent e) {
drawPanel.curveStart(e.getPoint());
}
@Override
public void mouseReleased(MouseEvent e) {
drawPanel.curveEnd(e.getPoint());
}
@Override
public void mouseDragged(MouseEvent e) {
drawPanel.curveAdd(e.getPoint());
}
}