0

How can I paint multiple rectangles to a JPanel?

This code here only allows me paint one rectangle at a time. It deletes the previously made rectangle once I start a new one. I need to write a program that paints more than 1 rectangle so it would probably look like a collage of rectangles of different colors.

public class Rectangles extends JFrame implements ActionListener {

int x1, y1, x2, y2;

JPanel main;
JPanel right;

JButton color1;
JButton color2;
JButton color3;
JButton color4;
JButton color5;
JButton color6;
JButton color7;
JButton color8;
JButton color9;
JButton color10;

Canvas left;

public Rectangles() {
    main = new JPanel(new BorderLayout(5, 5));
    main.setBorder(new EmptyBorder(20, 20, 20, 20));
    main.setBackground(new Color(0, 168, 165));

    right = new JPanel(new GridLayout(5, 2, 3, 3));
    right.setPreferredSize(new Dimension(150, 250));
    right.setBackground(new Color(0, 168, 165));

    color1 = new JButton();
    color1.setBackground(Color.LIGHT_GRAY);
    color1.addActionListener(this);
    color1.setBorder(new LineBorder(Color.BLACK, 5, false));

    color2 = new JButton();
    color2.setBackground(Color.BLUE);
    color2.addActionListener(this);
    color2.setBorder(new LineBorder(Color.BLACK, 5, false));

    color3 = new JButton();
    color3.setBackground(Color.CYAN);
    color3.addActionListener(this);
    color3.setBorder(new LineBorder(Color.BLACK, 5, false));

    color4 = new JButton();
    color4.setBackground(Color.DARK_GRAY);
    color4.addActionListener(this);
    color4.setBorder(new LineBorder(Color.BLACK, 5, false));

    color5 = new JButton();
    color5.setBackground(Color.GRAY);
    color5.addActionListener(this);
    color5.setBorder(new LineBorder(Color.BLACK, 5, false));

    color6 = new JButton();
    color6.setBackground(Color.GREEN);
    color6.addActionListener(this);
    color6.setBorder(new LineBorder(Color.BLACK, 5, false));

    color7 = new JButton();
    color7.setBackground(Color.YELLOW);
    color7.addActionListener(this);
    color7.setBorder(new LineBorder(Color.BLACK, 5, false));

    color8 = new JButton();
    color8.setBackground(Color.MAGENTA);
    color8.addActionListener(this);
    color8.setBorder(new LineBorder(Color.BLACK, 5, false));

    color9 = new JButton();
    color9.setBackground(Color.PINK);
    color9.addActionListener(this);
    color9.setBorder(new LineBorder(Color.BLACK, 5, false));

    color10 = new JButton();
    color10.setBackground(Color.RED);
    color10.addActionListener(this);
    color10.setBorder(new LineBorder(Color.BLACK, 5, false));

    right.add(color1);
    right.add(color2);
    right.add(color3);
    right.add(color4);
    right.add(color5);
    right.add(color6);
    right.add(color7);
    right.add(color8);
    right.add(color9);
    right.add(color10);

    left = new Canvas();
    left.setPreferredSize(new Dimension(500, 250));
    left.setBackground(Color.WHITE);
    left.setColor(Color.WHITE);
    left.setBorder(new LineBorder(Color.BLACK, 5, false));

    main.add(left, BorderLayout.CENTER);
    main.add(right, BorderLayout.EAST);

    this.add(main);
    this.pack();
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocation(450,75);
    this.setTitle("MARQUEZ Rectangles");
    this.setResizable(false);
    this.setVisible(true);
}

public static void main(String[] args) {
    Rectangles r = new Rectangles();
}

public void actionPerformed(ActionEvent e) {        
    if(e.getSource() == color1) {
        left.setColor(Color.LIGHT_GRAY);
    }

    else if(e.getSource() == color2) {
        left.setColor(Color.BLUE);
    }

    else if(e.getSource() == color3) {
        left.setColor(Color.CYAN);
    }

    else if(e.getSource() == color4) {
        left.setColor(Color.BLACK);
    }

    else if(e.getSource() == color5) {
        left.setColor(Color.GRAY);
    }

    else if(e.getSource() == color6) {
        left.setColor(Color.GREEN);
    }

    else if(e.getSource() == color7) {
        left.setColor(Color.YELLOW);
    }

    else if(e.getSource() == color8) {
        left.setColor(Color.MAGENTA);
    }

    else if(e.getSource() == color9) {
        left.setColor(Color.PINK);
    }

    else {
        left.setColor(Color.RED);
    }
}
}

This class paints the rectangle.

class Canvas extends JPanel implements  MouseListener,MouseMotionListener {
private int x,y,x1,y1;
Color color;

public Canvas() {
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
}

public void setColor(Color color) {
    this.color = color;
} 

public void mouseEntered(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

public void mousePressed(MouseEvent e) {
    x = e.getX();
    y = e.getY();
}

public void mouseDragged(MouseEvent e) {
    x1 = e.getX();
    y1 = e.getY();
    revalidate();
    repaint();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(color);
    g.fillRect(x, y, Math.abs(x-x1), Math.abs(y-y1));
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Be more specific with what your problem is please. – arynaq Sep 16 '13 at 15:14
  • So is it the 10 buttons that are not showing up? Or is it just the canvas class you made thats not working? – chancea Sep 16 '13 at 15:15
  • @chancea the code is working fine; however, it only paints one rectangle and whenever I paint a new one it deletes the previously made rectangle. – NoobProgrammer Sep 16 '13 at 15:21
  • @NoobProgrammer when you say "rectangle" are you referring to your `Canvas` class or your `JButtons` (color1, color2, etc...) – chancea Sep 16 '13 at 15:22
  • @chancea I'm referring to the Canvas because it draws the rectangle (I'm talking about shapes here). The buttons just determine the color of the rectangle. – NoobProgrammer Sep 16 '13 at 15:24
  • [Custom Painting Approaches](http://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/) gives examples of the 2 common ways to do this. – camickr Sep 16 '13 at 15:37

2 Answers2

2

The paint operations we do are 'transient' and will be destroyed the next time the component is painted. To get around that, there are two common techniques.

  1. Store a list of shapes (images, gradients and other painting operations), add the current drawing to the list, and when requested, paint them all.
  2. Draw to a BufferedImage that is painted when requested/needed. See this answer for an example.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

Your canvas only paints the most recent rectangle, swing painting works like that, once a paint is requested the previous buffer is cleared. What you need is a List<Rectangle>, every time you select a rectangle with the mouse, add it to the list and in the canvas draw every rectangle in the list. You will also need to save the color of the previous rectangles, either by making a a wrapper class for the rectangle that has color as a field or save that in a list too.

arynaq
  • 6,710
  • 9
  • 44
  • 74