简体   繁体   中英

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);

    }
}

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 ;)

Change repaint() to revalidate() after changing the component hierarchy. You'll notice that your current version paints the circle if you resize the window, because this revalidates the layout.

From the docs:

Revalidates the component hierarchy up to the nearest validate root. This method first invalidates the component hierarchy starting from this component up to the nearest validate root. Afterwards, the component hierarchy is validated starting from the nearest validate root. This is a convenience method supposed to help application developers avoid looking for validate roots manually. Basically, it's equivalent to first calling the invalidate() method on this component, and then calling the validate() method on the nearest validate root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM