问题描述
我的问题: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,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();
}
}
解决方法
如果您不想为此功能提供“撤消”功能,那么我看到的最简单的解决方案是绘制到BufferedImage,然后在SELECT a.id
FROM tableA a
WHERE a.id_list IN (select b.this_id from tableB b)
and a.id IN (select b.this_id from tableB b);
覆盖(而不是{{1 }} – 从不 paintComponent
)。这样,以前绘制的线条将一直保留,直到用新实例替换BufferedImage为止。
否则,如果您绝对不能走这条路,则创建一个新的自定义类,该类包含一个paint
或其他Shape类型的对象和一个Color,在用户绘制时创建这些对象,并将其存储到此类对象的列表,然后在您的(再次)paint
替代中对其进行绘制。通过这种方式,您可以将每条线(或其他Shape)与一种颜色相关联,并且这种关联将继续存在。
如上所述,我也建议不要覆盖Line2D
,而应该覆盖paintComponent
,因为paint
可以自动双缓冲,如果您决定制作动画,并且您也不想这样做不必担心会混淆组件的子组件和边框的绘制,而当您覆盖paintComponent
时,可能会冒险这么做。当然,通常在其覆盖的第一行中调用paint
方法。