1

I'm making a program that allows the user to draw multiple shapes on the screen and choose the desired color. At the current moment I have nine preset colors that the user can choose from. I plan on using a JColorChooser to allow the user to select different colors. However, I cannot figure out a way to store extra colors that may be chosen so that when the drawn shapes are repainted they will remain the same color that they were drawn with.

I have come up with a way to redraw the shapes in the order that they were drawn and with the color that they were drawn with, as shown below:

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();
}

So what happens is that when the user draws a shape, it is stored in an ArrayList of Shape objects. An integer is stored in a separate list based on what kind of shape was drawn and its color. Then when the program redraws all the shapes, it will go through each shape in the list, and it will give the shapes the color that they were drawn with and fill them in if necessary.

Now, what I'm trying to figure out is a way to transfer these colors to their own List or maybe even a Map to avoid having to create a ton of Color objects and adding to the already long list of code so that if the user decides to use other colors, the program will know what color belongs to what shape. So for example, if the user decided to draw a filled-in rectangle with the color 128,128,128; when the program redraws the shape it will know that the rectangle was filled in and was colored that specific shade of gray. But I haven't gone that far quite yet; right now I'm trying to find a solution that will work for just the nine colors that I have at the moment.

Does anyone have any ideas of how this can be done?

TNT
  • 2,900
  • 3
  • 23
  • 34

1 Answers1

0

It took a bit of research and looking around, but I finally found a solution to the problem.

Initially I thought about using a Map so I could add a key-value pair, and as long as I could access all the map's keys (objects that implement the Shape interface), I would be able to pair them with their values (Color objects) easily. So I came up with this:

Map<Shape,Color> map = new HashMap<Shape,Color>();

And this allowed me to store any shape drawn by the user as well as the corresponding color used. But now I had to find a way to retrieve all the stored shapes using a for loop so that I could repaint them. Doing a little research, I came across this answer, which shows how to iterate through a Map using said loop. So I was able to replace the switch statement with this:

for (Entry<Shape,Color> entry : map.entrySet()) {
    Shape shape = entry.getKey();
    Color color = entry.getValue();

    g2.setColor(color);
    g2.draw(shape);
}

However, I came across another problem: The key-value pairings were not in order, meaning that some shapes would randomly appear on top of others when they were previously behind them, and vice versa. So more research helped me determine that I should instead be using a LinkedHashMap instead, which preserves the order in which the key-value pairings are stored:

Map<Shape,Color> map = new LinkedHashMap<Shape,Color>();

And a bit of trial and error helped me to realize that since the key-value pairings were guaranteed to remain in order, I could always use the opNumList to determine whether the given shape should be drawn open or filled in.

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++;
}
Community
  • 1
  • 1
TNT
  • 2,900
  • 3
  • 23
  • 34