我正在java中实现一个paint应用程序。我在选择绘制的形状的颜色时遇到了麻烦。我能够选择颜色并用它绘制但是如果我绘制一个颜色变为蓝色,绘制一个蓝色矩形,将颜色更改为红色,绘制红色矩形,它也将蓝色矩形更改为红色,发生各种形状。我认为它是因为我在arrayList中保存了形状,它改变了所有形状的颜色,但是,我有不同形状的不同数组列表。
我正在尝试将颜色保存为静态color1并使用setPaint(color1)将颜色更改为所选颜色。任何帮助将不胜感激。
下面我有部分代码:
public class PaintAppFrame extends JFrame implements MouseListener, MouseMotionListener, ActionListener {
static final long serialVersionUID = 2L;
static int flag = 0;
// -------------------------------------------------------------------------
private JButton changeColor;
private JButton rectButton;
private JButton rectfillButton;
private JButton lineButton;
static Color color1;
static Graphics2D gr;
public static ArrayList<Shape> rectStruct = new ArrayList<Shape>();
public static ArrayList<Shape> rectFillStruct = new ArrayList<Shape>();
public static ArrayList<Shape> lineStruct = new ArrayList<Shape>();
private static Point mouseStart;
private static Point mouseEnd;
changeColor = new JButton("CHANGE COLOR");
changeColor.setActionCommand("color");
changeColor.addActionListener(this);
// added the menu goes here
image = Toolkit.getDefaultToolkit().getImage(".");
paintPanel = new PaintPanel();
paintPanel.addMouseMotionListener(this);
paintPanel.addMouseListener(this);
// make this a toolbar and images
Icon lineIcon = new ImageIcon("icons/line.png");
Icon rgbIcon = new ImageIcon("icons/color.png");
Icon rectIcon = new ImageIcon("icons/rect.png");
Icon rectfillIcon = new ImageIcon("icons/fullRect.png");
changeColor = new JButton(rgbIcon);
changeColor.setActionCommand("color");
changeColor.addActionListener(this);
rectButton = new JButton(rectIcon);
rectButton.setActionCommand("rectangle");
rectButton.addActionListener(this);
rectfillButton = new JButton(rectfillIcon);
rectfillButton.setActionCommand("rectanglefill");
rectfillButton.addActionListener(this);
lineButton = new JButton(lineIcon);
lineButton.setActionCommand("line");
lineButton.addActionListener(this);
JPanel buttons = new JPanel(new GridLayout());
buttons.setBorder(BorderFactory.createRaisedSoftBevelBorder());
buttons.setLayout(new GridLayout(16, 2));
buttons.add(changeColor);
buttons.add(rectButton);
buttons.add(rectfillButton);
buttons.add(lineButton);
paintCanvas = new JPanel(new BorderLayout());
paintCanvas.add(paintPanel, "Center");
paintCanvas.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
paintCanvas.setBackground(new Color(100, 100, 142));
paintCanvas.setPreferredSize(new Dimension(650, 520));
paintCanvas.setMaximumSize(new Dimension(2000, 1600));
}
public void mouseDragged(MouseEvent me) {
if (flag == 1) {
mouseEnd = new Point(me.getX(), me.getY());
repaint();
System.out.println("rect dragged");
}
else if (flag == 3) {
mouseEnd = new Point(me.getX(), me.getY());
repaint();
}
} else if (flag == 7) {
mouseEnd = new Point(me.getX(), me.getY());
repaint();
}
}
public void mouseMoved(MouseEvent me) {
}
public void mouseClicked(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
if (flag == 1) {
mouseStart = new Point(me.getX(), me.getY());
mouseEnd = mouseStart;
repaint();
}
else if (flag == 3) {
mouseStart = new Point(me.getX(), me.getY());
mouseEnd = mouseStart;
repaint();
}
else if (flag == 7) {
mouseStart = new Point(me.getX(), me.getY());
mouseEnd = mouseStart;
repaint();
}
}
public void mouseReleased(MouseEvent me) {
} else if (flag == 1) {
Shape r = createRect(mouseStart.x, mouseStart.y, me.getX(), me.getY());
rectStruct.add(r);
mouseStart = null;
mouseEnd = null;
repaint();
}
else if (flag == 3) {
Shape r = createFillRect(mouseStart.x, mouseStart.y, me.getX(), me.getY());
rectFillStruct.add(r);
mouseStart = null;
mouseEnd = null;
repaint();
}
else if (flag == 7) {
Shape r = createLine(mouseStart.x, mouseStart.y, me.getX(), me.getY());
lineStruct.add(r);
mouseStart = null;
mouseEnd = null;
repaint();
}
}
@SuppressWarnings("static-access")
public void actionPerformed(ActionEvent ae) {
String command = ae.getActionCommand();
Object source = ae.getSource();
// instantiate the filechooser
switch (command) {
case "color":
this.setPaintColor();
break;
case "rectangle":
flag = 1;
FLAG = 0;
this.paintRect(gr);
break;
case "rectanglefill":
flag = 3;
this.paintRectFill(gr);
break;
case "line":
flag = 7;
this.paintLine(gr);
break;
private void setPaintColor() {
Color color = JColorChooser.showDialog(null, "Choose Paint Color", Color.black);
color1 = color;
}
public static void paintRect(Graphics g) {
gr = (Graphics2D) g;
for (Shape s : rectStruct) {
gr.setPaint(color1);
gr.setStroke(new BasicStroke(2));
gr.draw(s);
// gr.setPaint(this.LINE_COLOR);
// gr.fill(s);
}
if (flag == 1) {
if (mouseStart != null && mouseEnd != null) {
//makes outline while dragging rectangle
gr.setPaint(Color.RED);
Shape r = createRect(mouseStart.x, mouseStart.y, mouseEnd.x, mouseEnd.y);
gr.draw(r);
}
}
}
public static void paintRectFill(Graphics g) {
gr = (Graphics2D) g;
for (Shape s : rectFillStruct) {
gr.setPaint(color1);
gr.setStroke(new BasicStroke(2));
gr.draw(s);
gr.fill(s);
}
if (flag == 3) {
if (mouseStart != null && mouseEnd != null) {
//makes outline while dragging rectangle
gr.setPaint(Color.RED);
Shape r = createFillRect(mouseStart.x, mouseStart.y, mouseEnd.x, mouseEnd.y);
gr.draw(r);
}
}
}
public static void paintLine(Graphics g) {
gr = (Graphics2D) g;
for (Shape s : lineStruct) {
gr.setPaint(color1);
gr.setStroke(new BasicStroke(2));
gr.draw(s);
gr.fill(s);
}
if (flag == 7) {
if (mouseStart != null && mouseEnd != null) {
//makes outline while dragging rectangle
gr.setPaint(Color.GREEN);
Shape r = createLine(mouseStart.x, mouseStart.y, mouseEnd.x, mouseEnd.y);
gr.draw(r);
}
}
}
public static Rectangle2D.Float createRect(int x1, int y1, int x2, int y2) {
return new Rectangle2D.Float(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
}
public static Rectangle2D.Float createFillRect(int x1, int y1, int x2, int y2) {
return new Rectangle2D.Float(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
}
public static Line2D.Float createLine(int x1, int y1, int x2, int y2) {
return new Line2D.Float(x1, y1, x2, y2);
}}
答案 0 :(得分:0)
正如之前在评论中已经提到的,您的程序应该存储每个形状的颜色。您可以创建一个可以存储形状和颜色的简单ColoredShape
类:
import java.awt.*;
public class ColoredShape {
private Shape shape;
private Color color;
public ColoredShape(Shape shape, Color color) {
this.shape = shape;
this.color = color;
}
public Shape getShape() {
return shape;
}
public Color getColor() {
return color;
}
}
在PaintAppFrame
类中,可以对矩形使用新的ColoredShape
类进行以下更改:
// Field definition change:
//public static ArrayList<Shape> rectStruct = new ArrayList<Shape>();
public static ArrayList<ColoredShape> rectStruct = new ArrayList<ColoredShape>();
// Method mouseReleased change:
//rectStruct.add(r);
rectStruct.add(new ColoredShape(r, color1));
// Method paintRect changes:
//for (Shape s : rectStruct) {
//gr.setPaint(PaintPanel.LINE_COLOR);
//[...]
//gr.draw(s);
for (ColoredShape coloredShape : rectStruct) {
gr.setPaint(coloredShape.getColor());
[...]
gr.draw(coloredShape.getShape());
在PaintPanel
类中,可以对这些更改使用新的ColoredShape
类作为矩形:
// Field definition added:
private static ArrayList<ColoredShape> redoStructNew = new ArrayList<ColoredShape>();
// Method undo change:
//redoStruct.add(PaintAppFrame.rectStruct.get(i));
redoStructNew.add(PaintAppFrame.rectStruct.get(i));
// Method redo changes:
//if (!PaintAppFrame.rectStruct.isEmpty() && !redoStruct.isEmpty()) {
//for (int i = 0; i < redoStruct.size(); i++) {
//PaintAppFrame.rectStruct.add(redoStruct.get(i));
//[...]
if (!PaintAppFrame.rectStruct.isEmpty() && !redoStructNew.isEmpty()) {
for (int i = 0; i < redoStructNew.size(); i++) {
PaintAppFrame.rectStruct.add(redoStructNew.get(i));
[...]
您可以以类似的方式更改其他类型形状的代码。
修改1:细分
对于细分市场,您还需要存储所有相关数据。查看drawInk
方法,我认为您需要:线坐标,颜色和笔触。因此,不是仅存储坐标(参见allStrokes
字段),而是可以在类中存储线段列表,如下所示:
import java.awt.*;
import java.awt.geom.Line2D;
public class LineSegment {
private Line2D.Double coordinates;
private Color color;
private Stroke stroke;
public LineSegment(Line2D.Double coordinates, Color color, Stroke stroke) {
this.coordinates = coordinates;
this.color = color;
this.stroke = stroke;
}
public void draw(Graphics2D graphics2D) {
graphics2D.setColor(color);
graphics2D.setStroke(stroke);
graphics2D.draw(coordinates);
}
}
编辑2:绘制顺序
当前绘制不同图形对象的顺序取决于对象的类型,而不是用户添加对象时的顺序。我认为解决这个问题的最佳方法是将所有图形对象存储在一个列表中,这将决定绘图顺序。您可以创建GraphicalObject
,ColoredShape
和Entity
类扩展的超类LineSegment
。该类甚至可以定义共享/可覆盖的方法,如draw
(已在LineSegment中)。 GraphicalObject
类可以非常简单:
import java.awt.Graphics2D;
public abstract class GraphicalObject {
public abstract void draw(Graphics2D graphics2D);
}
修改ColoredShape
,Entity
和LineSegment
类,如下所示:
public class LineSegment extends GraphicalObject {
// [...]
// Each class should implement the draw method:
public void draw(Graphics2D graphics2D) {
// [...]
}
}
现在,您可以使用单个图形对象列表替换存储形状,线条和实体的所有数据结构:
private List<GraphicalObject> graphicalObjects = new ArrayList<>();
//public static ArrayList<ColoredShape> rectStruct = new ArrayList<ColoredShape>();
// [...]
//public static ArrayList<ColoredShape> lineStruct = new ArrayList<ColoredShape>();
确保使用此新列表存储要在PaintPanel.paintComponent
方法中绘制的所有图形对象(目前似乎某些对象存储在PaintAppFrame
类中,而其他对象存储在PaintPanel
类中paintInkStrokes(g);
paintEraser(g);
PaintAppFrame.paintRect(g);
PaintAppFrame.paintCircle(g);
PaintAppFrame.paintRectFill(g);
PaintAppFrame.paintFillCircle(g);
PaintAppFrame.paintRoundRectangle(g);
PaintAppFrame.paintRoundRectangleFill(g);
PaintAppFrame.paintLine(g);
paintEntities(g);
类):
PaintAppFrame
一些额外的建议:我认为也可以使代码的某些部分能够处理所有类型的形状,而不是为每种类型提供代码。例如,在paintRect
类中,paintLine
直到undo
方法有很多共同的代码。同样在redo
类的PaintPanel
和rad2deg()
方法中,有很多代码块几乎相同。