Search code examples
javaswinggraphicsacm-java-libraries

How can I add shapes automatically in paintComponent?


As a beginner, whenever I want to add graphical shapes inside the frame I do something like this:

public void paintComponent(Graphics g) {
    super.paintComponent(g); 
    g.fillRect(0, 0, 10, 10);
    g.fillOval(10,10,10,10);
}

How do I draw an unlimited number of shapes automatically inside the frame? If I follow the way I did above I only have a limited number of shapes(Rect, Oval and nothing else).

I'm looking for something different, for example, whenever a method addStuff(x, y) has called, it draws "Stuff" automatically at the coordinate x and y without having to edit anything inside paintComponent manually again.

I used to do this with the acm package and it was easy. Just like the code below.

for (int i = 0; i < NCIRCLES; i++) {
    double r = rgen.nextDouble(MIN_RADIUS, MAX_RADIUS);
    double x = rgen.nextDouble(0, getWidth() - 2 * r);
    double y = rgen.nextDouble(0, getHeight() - 2 * r);
    GOval circle = new GOval(x, y, 2 * r, 2 * r);
    circle.setFilled(true);
    circle.setColor(rgen.nextColor());
    add(circle);
}

As you can see above, I can add as many circles as I want, I know it can take pages to explain this but I just want a brief instruction on how to create something similar to the code above without relying on acm package.


Solution

  • I would use an abstract class to define this behavior.

    abstract class OpalDraw {
        protected int x1, y1, x2, y2;
        protected OpalDraw(int x1, int y1, int x2, int y2) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
        }
        abstract public void draw(Graphics g);
    }
    
    class OpalOval {
        public OpalOval(int x1, int y1, int x2, int y2) { super(x1,y1,x2,y1); }
        public void draw(Graphics g) {
            g.drawOval(x1,y1,x2,y1);
        }
    }
    
    class OpalRect {
        public OpalRect(int x1, int y1, int x2, int y2) { super(x1,y1,x2,y1); }
        public void draw(Graphics g) {
            g.drawRect(x1,y1,x2,y1);
        }
    }
    

    Then in your painting container you can have

    addOval(int x1, int y1, int x2, int y2) {
        myDraws.add(new OpalOval(x1,x2,y1,y2);
    }
    
    addRect(int x1, int y1, int x2, int y2) {
        myDraws.add(new OpalRect(x1,x2,y1,y2);
    }
    

    Then later inside paintComponent(Graphics) you can

    for(OpalDraw draw : myDraws) draw.draw(g);