【发布时间】:2021-01-28 09:32:31
【问题描述】:
我的问题: graphics2D 对象重新着色 ArrayList 中的每个点。当我改变颜色时,我将如何做到这一点,它不会改变以前的颜色?我的猜测是改变 for 循环在 PaintApp 中的交互方式,但我不确定我应该做什么。感谢您的帮助!
我的代码:
PaintApp.java
package paint;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class PaintApp extends JPanel {
private List<List<Point>> points;
private JFrame frame = new JFrame("Sketch MSPaint");
private JMenuBar bar = new JMenuBar();
private JMenu file = new JMenu("File");
private JMenu colors = new JMenu("Colors");
private JMenuItem quit = new JMenuItem("Quit");
private JMenuItem red = new JMenuItem("Red");
private JMenuItem blue = new JMenuItem("Blue");
private JMenuItem green = new JMenuItem("Green");
private JMenuItem orange = new JMenuItem("Orange");
private JMenuItem pink = new JMenuItem("Pink");
private JMenuItem cyan = new JMenuItem("Cyan");
private JMenuItem clear = new JMenuItem("Clear");
private boolean clearBoard = false, blackColor, redColor, blueColor, greenColor, orangeColor, pinkColor, cyanColor;
public PaintApp(Dimension d) {
this.setSize(d);
this.setPreferredSize(d);
points = new ArrayList<>();
MouseAdapter ma = new MouseAdapter() {
private List<Point> currentPath;
@Override
public void mousePressed(MouseEvent e) {
currentPath = new ArrayList<>();
currentPath.add(e.getPoint());
points.add(currentPath);
}
@Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
currentPath.add(dragPoint);
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
currentPath = null;
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.clearRect(0, 0, frame.getWidth(), frame.getHeight());
for (List<Point> path : points) {
Point from = null;
for (Point p : path) {
if (from != null) {
if (redColor) {
g2d.setColor(Color.red);
} else if (blueColor) {
g2d.setColor(Color.blue);
} else if (greenColor) {
g2d.setColor(Color.green);
} else if (orangeColor) {
g2d.setColor(Color.orange);
} else if (pinkColor) {
g2d.setColor(Color.pink);
} else if (cyanColor) {
g2d.setColor(Color.cyan);
} else {
g2d.setColor(Color.black);
}
g2d.drawLine(from.x, from.y, p.x, p.y);
}
from = p;
}
}
g2d.dispose();
}
public void initBar() {
bar.add(file);
file.add(clear);
clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
points = new ArrayList<>();
repaint();
}
});
file.add(quit);
quit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
bar.add(colors);
colors.add(red);
red.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = true;
blueColor = false;
greenColor = false;
orangeColor = false;
pinkColor = false;
cyanColor = false;
repaint();
}
});
colors.add(orange);
orange.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = false;
blueColor = false;
greenColor = false;
orangeColor = true;
pinkColor = false;
cyanColor = false;
repaint();
}
});
colors.add(blue);
blue.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = false;
blueColor = true;
greenColor = false;
orangeColor = false;
pinkColor = false;
cyanColor = false;
repaint();
}
});
colors.add(green);
quit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = false;
blueColor = false;
greenColor = true;
orangeColor = false;
pinkColor = false;
cyanColor = false;
repaint();
}
});
colors.add(pink);
quit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = false;
blueColor = false;
greenColor = false;
orangeColor = false;
pinkColor = true;
cyanColor = false;
repaint();
}
});
colors.add(cyan);
quit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
redColor = false;
blueColor = false;
greenColor = false;
orangeColor = false;
pinkColor = false;
cyanColor = true;
repaint();
}
});
frame.setJMenuBar(bar);
}
public void show() {
frame.add(this);
initBar();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Main.java
package paint;
import java.awt.Dimension;
public class Main {
public static void main(String[] args) {
PaintApp app = new PaintApp(new Dimension(700,700));
app.show();
}
}
【问题讨论】:
-
您应该创建一个自定义对象,其中包含您要绘制的所有属性。在您的示例中,您的对象可能包含一个 Line 对象和您要绘制的对象的 Color。有关工作示例,请参阅:Custom Painting Approaches。它绘制“彩色矩形”,但概念是相同的。
-
最终我确实想添加一个撤消按钮 - 在上面的链接中提出的建议。
-
这是唯一的方法吗?我不太确定我应该在缓冲图像上绘画,正如下面的人所说,没有办法添加撤消按钮,对吗?
-
该链接不建议使用缓冲图像方法。它提供了另一种方法,包括如何使用鼠标绘制矩形。
-
Abys,@camickr 提出的建议类似于我回答的第二部分,即避免使用 BufferedImage 的部分。请重新阅读他的第一条评论和我的回答。
标签: java swing arraylist graphics paint