Main Tutorials

Java Swing – Draw shapes dynamically example

swing-draw-shapes-3

In this article we create an application that randomly puts shapes on a JPanel. The user can choose between the different shapes our application supports as well as the amount that will be drawn. As a design decision our application can make circles and stars. You can download the example at the end of the article and experiment with more shapes, random colours, random sizes etc.

1. The Circle

The constructor receives the x and y coordinates of the circle while the diameter is set to 10px.

Circle.java

package com.mkyong.dynamicshapes;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

public class Circle {

    int x, y, width, height;

    public Circle(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void draw(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Ellipse2D.Double circle = new Ellipse2D.Double(x, y, 10, 10);

        g2d.setColor(Color.GRAY);
        g2d.fill(circle);
    }

}

2. The Star

To draw the star we use GeneralPath class. We have two arrays for x and y coordinates that the GeneralPath has to follow to draw the star. The line starts from (9,0) and moves through the set of points to reach (3,18) and finally closePath() which means “return to where we started”.

Draw this on paper using Java’s coordinate system and you will have a star! There is not one way to draw a star. You can play around with the numbers and make your own star, or other shapes even!

Star.java

package com.mkyong.dynamicshapes;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;

public class Star {

    int x, y, width, height;

    public Star(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void draw(Graphics g) {
        int xPoints[] = {9, 15, 0, 18, 3};
        int yPoints[] = {0, 18, 6, 6, 18};

        Graphics2D g2d = (Graphics2D) g;
        GeneralPath star = new GeneralPath();

        star.moveTo(xPoints[0] + x, yPoints[0] + y);
        for (int i = 1; i < xPoints.length; i++) {
            star.lineTo(xPoints[i] + x, yPoints[i] + y);
        }
        star.closePath();

        g2d.setColor(Color.YELLOW);
        g2d.fill(star);
    }
}

3. The Application

In the main method we ask the user for the amount and type of shapes, then create the JFrame and initialize the JPanel with a call to DynamicShapes class. The DynamicShapes class which extends JPanel draws through paintComponent() method the shapes that were added to the List. The List gets populated from the constructor of DynamicShapes class which calls the method for each shape according to user input.

DynamicShapes.java

package com.mkyong.dynamicshapes;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class DynamicShapes extends JPanel {

    private List<Object> shapes = new ArrayList<>();
    private Random random = new Random();

    public DynamicShapes(int i, String shape) {
        setBackground(Color.BLACK);
        setPreferredSize(new Dimension(400, 400));

        switch (shape) {
            case "Circles":
                for (int j = 0; j < i; j++) {
                    addCircle(390, 390);
                }
                break;
            case "Stars":
                for (int j = 0; j < i; j++) {
                    addStar(380, 380);
                }
                break;
            case "Both":
                int mid = i / 2;
                for (int j = 0; j < mid; j++) {
                    addCircle(390, 390);
                }
                for (int j = mid; j < i; j++) {
                    addStar(380, 380);
                }
                break;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Object s : shapes) {
            if (s instanceof Circle) {
                ((Circle) s).draw(g);
            } else if (s instanceof Star) {
                ((Star) s).draw(g);
            }
        }
    }

    public void addCircle(int maxX, int maxY) {
        shapes.add(new Circle(random.nextInt(maxX), random.nextInt(maxY)));
        repaint();
    }

    public void addStar(int maxX, int maxY) {
        shapes.add(new Star(random.nextInt(maxX), random.nextInt(maxY)));
        repaint();
    }

    public static void main(String[] args) {

        String shapeAmount = JOptionPane.showInputDialog(null,
                "How many shapes?", "Random Shapes...", JOptionPane.PLAIN_MESSAGE);
        int amount = Integer.parseInt(shapeAmount);

        String shapes[] = {"Stars", "Circles", "Both"};
        String shape = (String) JOptionPane.showInputDialog(null,
                "Pick the shape you want", "Random Shapes...",
                JOptionPane.PLAIN_MESSAGE, null, shapes, shapes[0]);

        JFrame frame = new JFrame();
        frame.add(new DynamicShapes(amount, shape));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

Output:

Type “200” and click “OK”

swing-draw-shapes-1

Select “Both” and click “OK”

swing-draw-shapes-2

The result is 100 stars and 100 circles randomly placed within the JPanel:

swing-draw-shapes-3

100 shapes in all combinations:

swing-draw-shapes-4

Download Source Code

Download – DrawShapesDynamically.zip (4 KB)

References

  1. Java coordinate tutorial
  2. java.awt.geom.GeneralPath JavaDoc
  3. javax.swing.JPanel JavaDoc

About Author

author image
Marilena Panagiotidou is a senior at University of the Aegean, in the department of Information and Communication Systems Engineering. She is passionate about programming in a wide range of languages. You can contact her at [email protected] or through her LinkedIn.

Comments

Subscribe
Notify of
1 Comment
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
MacGregor
6 years ago

Wouldn’t be better to create a DrawableShape interface with method draw()?