Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding shapes to JPanel on a button click

Tags:

java

swing

paint

I have a Class Circle with a button and a Class with a jPanel what i want to do is when that button is clicked a circle will be drawn on the panel and each time i click that button and change x and y "some how not implemented here" i got a circle on the JPanel over and over . How to do that, or is there a way to do what i descriped regardless of my code but i want the class circle to extends Shape.

public class Window{

  private JFrame frame;
  private JPanel panel = new JPanel();
  Circle c = new Circle(frame, panel);
  // some other buttons 
  .
  .
 // some code to set the panel grid bag constaraints and background then
 frame.getContentPane().add(panel, gbc_panel);
}

then the Circle Class

public class Circle extends Shape implements ActionListener{

  private JPanel Panel;
  private GridBagConstraints gbc_btnCircle;
  private JButton btnCircle;

  public void setPanel(JPanel panel) {
      Panel = panel;
  }

 public Circle(JFrame frame, JPanel panel){
    btnCircle = new JButton("Circle");
    // some code to set grid bag constraint then
    frame.getContentPane().add(btnCircle, gbc_btnCircle);
    setPanel(panel);        
    btnCircle.addActionListener(this);

 }

  public void paint(Graphics g) {
      super.paintComponents(g);
      g.setColor(Color.red);        
      g.fillOval(100, 100, 100, 100);     
      Panel.add(this);
  }

  public void actionPerformed(ActionEvent arg0) {
    repaint();      
  }
}
like image 757
Alaa Othman Avatar asked Mar 19 '23 00:03

Alaa Othman


1 Answers

You kinda have the wrong idea. In your drawing panel, you should have a List<Circle>. And in the paintComponent method of the drawing panel, you should iterate through the list to draw each circle

class Circle {
    int x, int y, int width, int height;
    public Circle (int x, int y, int width, int height) {
        ... set em
    }
    public void draw(Graphics g) {
        g.fillOval(x, y, width, height);
    }
}
class DrawingPanel extends JPanel {
    List<Circle> circles = new ArrayList<>();

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Circle circle : circles) {
            circle.draw(g);
        }
    }

    // Dont forget to override public Dimension getPreferredSize()
}

To add more Circles to the list, just have a addCircle method in the DrawingPanel class

public void addCircle(Circle circle) {
    circles.add(circle);
    repaint();
}

As far as the button, you should be creating it in the Window class. In the ActionListener, just create a new Circle and add it the DrawingPanel by calling the addCircle method


An aside, Circle doesn't need the extend Shape. The Shape API already has an Ellipse2D class, which you can create circles from

class DrawingPanel extends JPanel {
    List<Ellipse2D> circles = new ArrayList<>();

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        for (Ellipse2D circle : circles) {
            g2.fill(circle);
        }
        g2.dispose();
    }
    // Dont forget to override public Dimension getPreferredSize()
}
  • See 2D Graphics

UPDATE: full example

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CirclesDemo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new CirclesDemo();
            }
        });
    }

    public CirclesDemo() {
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.add(createButton(), BorderLayout.PAGE_END);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private final DrawingPanel panel = new DrawingPanel();

    private JButton createButton() {
        JButton button = new JButton("Add Circle");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                int[] circleValues = generateRandomValues(300, 300, 50, 150);
                int x = circleValues[0];
                int y = circleValues[1];
                int width = circleValues[2];
                int height = width;
                Circle circle = new Circle(x, y, width, height);
                panel.addCircle(circle);
            }
        });
        return button;
    }

    private int[] generateRandomValues(int maxX, int maxY, 
                                       int minSize, int maxSize) {
        Random random = new Random();
        int[] values = new int[3];
        values[0] = random.nextInt(maxX);
        values[1] = random.nextInt(maxY);
        values[2] = Math.min(random.nextInt(maxSize) + minSize, maxSize);
        return values;
    }

    class Circle {

        int x, y, width, height;

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

        public void draw(Graphics g) {
            g.drawOval(x, y, width, height);
        }
    }

    class DrawingPanel extends JPanel {

        List<Circle> circles = new ArrayList<>();

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (Circle circle : circles) {
                circle.draw(g);
            }
        }

        public void addCircle(Circle circle) {
            circles.add(circle);
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }
}
like image 117
Paul Samsotha Avatar answered Mar 29 '23 20:03

Paul Samsotha