Search code examples
javaswingjframegraphics2d

Java Simple Shape Program


I am trying to make this simple program using GUI which creates a circle once the JButton is pressed. I have been working on this and trying to figure out why this isn't working for a couples hours. I looked at similar code on stackoverflow with people with similar questions like this, however, I still cannot figure this out. Can someone please tell me where I went wrong and why I am incorrect? Thank you.

public class ColorShape {

    public static void main(String[] args) {

        CreatePanel c = new CreatePanel();
        c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        c.setSize(300, 450);
        c.setVisible(true);

    }
}

public class CreatePanel extends JFrame {

    private JButton DC;
    private BorderLayout layout;

    public CreatePanel() {
        super("Color-Shape");
        layout = new BorderLayout();
        setLayout(layout);

        DC = new JButton("Circle");
        DC.addActionListener(
                new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                DrawCirc circ = new DrawCirc();
                add(circ);
                repaint();
            }
        }
        );
        add(DC, BorderLayout.NORTH);

    }
}

public class DrawCirc extends JPanel {

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.cyan);
        g.fillOval(100, 100, 50, 50);

    }
}

Solution

  • Well, your first problem is, DrawCirc provides no sizing hints, which means it's default size is going to be 0x0

    public class DrawCirc extends JPanel {
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(150, 150);
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.cyan);
            g.fillOval(100, 100, 50, 50);
        }
    }
    

    Also, remember, the Graphics context is translated so that 0x0 is the top left corner of the component.

    The second problem is, Swing is lazy. It allows you to make a number of changes to the UI and then batch process them. This means that when you've finished updating the UI, you have to call both revalidate and repaint to trigger a layout and paint pass

    DC.addActionListener(
            new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            DrawCirc circ = new DrawCirc();
            add(circ);
            revalidate();
            repaint();
        }
    });
    

    Both of these issues are not uncommon. You should spend some more time understanding the layout management system as it will make your life simpler ;)