【发布时间】:2014-10-26 03:04:18
【问题描述】:
所以我正在尝试创建一个程序,用户可以在其中绘制 JPanel 上的形状。但是我在按顺序显示形状时遇到了问题。我想出了一种从头到尾显示形状(现在只是矩形)的糟糕方法:将每个矩形放在 Set 中,然后将整数存储在 List 中,以确定矩形的颜色以及是否填写。例如,考虑下面的列表:
2 - 红色矩形,打开
3 - 红色矩形,填充
7 - 橙色矩形,打开
8 - 橙色矩形,填充
...
42 - 黑色矩形,打开
43 - 黑色矩形,填充
因此,如果用户要绘制一个打开的黑色矩形,程序会将数字 42 存储在 List 中,然后当程序返回绘制每个矩形时,它会查找打开的数字对应矩形,设置颜色并绘制或填充矩形。
但这有一个复杂的地方:比如说,我画了几个红色矩形,然后切换到绘制橙色矩形。有时当我完成一个橙色矩形的绘制时,我之前绘制的其中一个矩形会变成橙色,尽管列表中的相应整数指向其他方向。我知道这可能源于我按顺序绘制所有矩形的糟糕尝试,但我想不出任何其他方法。
矩形正在改变颜色的事实是否源于我无法控制的另一件关于绘画的事情?有没有更好的方法让我按顺序存储和重新绘制形状?
public class GraphicsTest {
public GraphicsTest() {
JFrame frame = new JFrame("");
Painter painter = new Painter();
frame.setLayout(new BorderLayout());
frame.setJMenuBar(painter.createMenuBar());
frame.add(painter,BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750,488);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GraphicsTest();
}
});
}
public class Painter extends JPanel implements MouseListener, MouseMotionListener {
private final Color purple = new Color(255,0,255);
private final Color brown = new Color(171,100,28);
private Rectangle dummyRect = new Rectangle(); // Dummy rectangle that shows up when the user attempts to draw a rectangle
private Set<Shape> shapeSet = new HashSet<Shape>();
private List<Color> colorList = new ArrayList<Color>();
private List<Integer> opNumList = new ArrayList<Integer>();
// Point used for drawing dummy rectangle
private Point clickPoint;
// Initial color
private Color color = Color.black;
// int variables that determine the position of various on-screen objects
private int dragX = 0, dragY = 0, downX = 0, downY = 0, upX = 0, upY = 0;
public Painter() {
// Adding colors to the ArrayList
/*colorList.add(Color.red);
colorList.add(Color.orange);
colorList.add(Color.yellow);
colorList.add(Color.green);
colorList.add(Color.blue);
colorList.add(purple);
colorList.add(brown);
colorList.add(Color.white);
colorList.add(Color.black);*/
// Adding listeners so that the mouse may be used to draw various objects
addMouseListener(this);
addMouseMotionListener(this);
}
/**
* Driving method of this program that displays all on-screen components
**/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int index = 0;
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
// Displaying the rectangle as it is drawn
if (dummyRect.width > 0 && dummyRect.height > 0)
if (cbFillItem.isSelected())
g2.fill(dummyRect);
else
g2.draw(dummyRect);
// Storing the rectangles in the HashSet
if (downX > upX && downY > upY)
shapeSet.add(new Rectangle(upX,upY,downX-upX,downY-upY));
else if (downX > upX && downY < upY)
shapeSet.add(new Rectangle(upX,downY,downX-upX,upY-downY));
else if (downX < upX && downY > upY)
shapeSet.add(new Rectangle(downX,upY,upX-downX,downY-upY));
else
shapeSet.add(new Rectangle(downX,downY,upX-downX,upY-downY));
try {
for (Shape s : shapeSet) {
if (s instanceof Rectangle) {
Rectangle r = (Rectangle) s;
if (r.width == 0 && r.height == 0)
shapeSet.remove(s);
}
}
} catch (ConcurrentModificationException ex) {}
// System.out.println("Size: " + shapeSet.size());
if (!opNumList.isEmpty()) {
for (Shape s : shapeSet) {
//System.out.println("Index: " + index);
//System.out.println("Element: " + opNumList.get(index));
//System.out.println();
switch (opNumList.get(index)) {
case 2: g2.setColor(Color.red); g2.fill(s); break;
case 3: g2.setColor(Color.red); g2.draw(s); break;
case 7: g2.setColor(Color.orange); g2.fill(s); break;
case 8: g2.setColor(Color.orange); g2.draw(s); break;
case 12: g2.setColor(Color.yellow); g2.fill(s); break;
case 13: g2.setColor(Color.yellow); g2.draw(s); break;
case 17: g2.setColor(Color.green); g2.fill(s); break;
case 18: g2.setColor(Color.green); g2.draw(s); break;
case 22: g2.setColor(Color.blue); g2.fill(s); break;
case 23: g2.setColor(Color.blue); g2.draw(s); break;
case 27: g2.setColor(purple); g2.fill(s); break;
case 28: g2.setColor(purple); g2.draw(s); break;
case 32: g2.setColor(brown); g2.fill(s); break;
case 33: g2.setColor(brown); g2.draw(s); break;
case 37: g2.setColor(Color.white); g2.fill(s); break;
case 38: g2.setColor(Color.white); g2.draw(s); break;
case 42: g2.setColor(Color.black); g2.fill(s); break;
case 43: g2.setColor(Color.black); g2.draw(s); break;
default: return;
}
index++;
}
}
}
/**
* MouseListener interface methods
**/
@Override
public void mouseClicked(MouseEvent ev) {}
@Override
public void mouseEntered(MouseEvent ev) {}
@Override
public void mouseExited(MouseEvent ev) {}
@Override
public void mousePressed(MouseEvent ev) {
clickPoint = new Point(ev.getPoint());
upX = ev.getX();
upY = ev.getY();
}
@Override
public void mouseReleased(MouseEvent ev) {
upX = ev.getX();
upY = ev.getY();
if (color == Color.red) {
if (cbFillItem.isSelected())
opNumList.add(2);
else
opNumList.add(3);
}
if (color == Color.orange) {
if (cbFillItem.isSelected())
opNumList.add(7);
else
opNumList.add(8);
}
if (color == Color.yellow) {
if (cbFillItem.isSelected())
opNumList.add(12);
else
opNumList.add(13);
}
if (color == Color.green) {
if (cbFillItem.isSelected())
opNumList.add(17);
else
opNumList.add(18);
}
if (color == Color.blue) {
if (cbFillItem.isSelected())
opNumList.add(22);
else
opNumList.add(23);
}
if (color == purple) {
if (cbFillItem.isSelected())
opNumList.add(27);
else
opNumList.add(28);
}
if (color == brown) {
if (cbFillItem.isSelected())
opNumList.add(32);
else
opNumList.add(33);
}
if (color == Color.white) {
if (cbFillItem.isSelected())
opNumList.add(37);
else
opNumList.add(38);
}
if (color == Color.black) {
if (cbFillItem.isSelected())
opNumList.add(42);
else
opNumList.add(43);
}
repaint();
}
/**
* MouseMotionListener interface methods
**/
@Override
public void mouseMoved(MouseEvent ev) {}
@Override
public void mouseDragged(MouseEvent ev) {
dragX = ev.getX();
dragY = ev.getY();
int minX = Math.min(ev.getX(), clickPoint.x);
int minY = Math.min(ev.getY(), clickPoint.y);
int maxX = Math.max(ev.getX(), clickPoint.x);
int maxY = Math.max(ev.getY(), clickPoint.y);
dummyRect.x = minX;
dummyRect.y = minY;
dummyRect.width = maxX - minX;
dummyRect.height = maxY - minY;
repaint();
}
}
}
【问题讨论】: