我正在制作一个程序,允许用户在屏幕上绘制多个形状并选择所需的颜色。目前,我有九种预设颜色可供用户选择。我计划使用JColorChooser
允许用户选择不同的颜色。但是,我无法找到一种方法来存储可以选择的其他颜色,以便在重新绘制绘制的形状时,它们将保持与绘制时相同的颜色。
我想出了一种以绘制顺序和绘制颜色重新绘制形状的方法,如下所示:
private List<Shape> shapeList = new ArrayList<Shape>();
private List<Integer> opNumList = new ArrayList<Integer>();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int index = 0;
Graphics2D g2 = (Graphics2D) g.create();
if (!opNumList.isEmpty()) {
for (Shape s : shapeList) {
switch (opNumList.get(index))
case 0: g2.setColor(Color.red); g2.draw(s); break;
case 1: g2.setColor(Color.red); g2.fill(s); break;
case 2: g2.setColor(Color.orange); g2.draw(s); break;
case 3: g2.setColor(Color.orange); g2.fill(s); break;
case 4: g2.setColor(Color.yellow); g2.draw(s); break;
case 5: g2.setColor(Color.yellow); g2.fill(s); break;
case 6: g2.setColor(Color.green); g2.draw(s); break;
case 7: g2.setColor(Color.green); g2.fill(s); break;
case 8: g2.setColor(Color.blue); g2.draw(s); break;
case 9: g2.setColor(Color.blue); g2.fill(s); break;
case 10: g2.setColor(purple); g2.draw(s); break;
case 11: g2.setColor(purple); g2.fill(s); break;
case 12: g2.setColor(brown); g2.draw(s); break;
case 13: g2.setColor(brown); g2.fill(s); break;
case 14: g2.setColor(Color.white); g2.draw(s); break;
case 15: g2.setColor(Color.white); g2.fill(s); break;
case 16: g2.setColor(Color.black); g2.draw(s); break;
case 17: g2.setColor(Color.black); g2.fill(s); break;
default: return;
}
index++;
}
}
}
@Override
public void mouseReleased(MouseEvent ev) {
if (color == Color.red) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(0);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(1);
}
if (color == Color.orange) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(2);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(3);
}
if (color == Color.yellow) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(4);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(5);
}
if (color == Color.green) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(6);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(7);
}
if (color == Color.blue) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(8);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(9);
}
if (color == purple) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(10);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(11);
}
if (color == brown) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(12);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(13);
}
if (color == Color.white) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(14);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(15);
}
if (color == Color.black) {
if (toolNum == LINE || (toolNum == RECTANGLE && !cbFillItem.isSelected()) || (toolNum == OVAL && !cbFillItem.isSelected()))
opNumList.add(16);
if ((toolNum == RECTANGLE || toolNum == OVAL) && cbFillItem.isSelected())
opNumList.add(17);
}
repaint();
}
因此,发生的情况是,当用户绘制形状时,它存储在
ArrayList
个Shape
对象中。根据绘制的形状及其颜色,将整数存储在单独的列表中。然后,当程序重新绘制所有形状时,它将遍历列表中的每个形状,并为形状提供绘制时所用的颜色,并在必要时进行填充。现在,我想找出的一种方法是将这些颜色转移到自己的
List
或什至是Map
,以避免不得不创建大量的Color
对象并将其添加到已经很长的列表中代码,以便用户决定使用其他颜色,程序将知道哪种颜色属于哪种形状。因此,例如,如果用户决定绘制一个颜色为128,128,128的填充矩形;当程序重新绘制形状时,它将知道该矩形已被填充并被着色为特定的灰色阴影。但是我还没有走那么远。现在,我正在尝试寻找一种解决方案,该解决方案仅适用于目前的九种颜色。有人对如何做到这一点有任何想法吗?
最佳答案
经过一些研究并四处寻找,但我终于找到了解决该问题的方法。
最初,我考虑使用Map
,所以我可以添加一个键值对,只要我可以访问地图的所有键(实现Shape
接口的对象),就可以将它们与它们配对值(Color
对象)。所以我想出了这个:
Map<Shape,Color> map = new HashMap<Shape,Color>();
这使我可以存储用户绘制的任何形状以及所使用的相应颜色。但是现在我必须找到一种使用
for
循环检索所有存储形状的方法,以便可以重新绘制它们。做一点研究,我遇到了this answer,它显示了如何使用所述循环遍历Map
。因此,我可以用以下内容替换switch
语句:for (Entry<Shape,Color> entry : map.entrySet()) {
Shape shape = entry.getKey();
Color color = entry.getValue();
g2.setColor(color);
g2.draw(shape);
}
但是,我遇到了另一个问题:键值配对不按顺序排列,这意味着某些形状在以前位于它们之后时会随机出现在其他形状的顶部,反之亦然。因此,更多的研究帮助我确定我应该改为使用
LinkedHashMap
,它保留了键值对的存储顺序:Map<Shape,Color> map = new LinkedHashMap<Shape,Color>();
反复试验使我意识到,由于键值对保证可以保持顺序,因此我总是可以使用
opNumList
来确定应将给定的形状绘制为打开还是填充。int index = 0;
for (Entry<Shape,Color> entry : map.entrySet()) {
Shape shape = entry.getKey();
Color color = entry.getValue();
g2.setColor(color);
if (!opNumList.isEmpty()) {
if (opNumList.get(index) == 0)
g2.draw(shape);
if (opNumList.get(index) == 1)
g2.fill(shape);
}
index++;
}
关于java - 用额外的颜色顺序着色形状,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26661144/