Search code examples
javaawtgraphics2d

Why can I draw on the frame but not inside a container?


Could you please assist? I would like to draw a circle. So I made the Circle class below. I can draw the Circle by adding it to the Frame, but not by adding it to a Panel and then adding the Panel to the Frame. I would like to do the latter, because I want multiple Circles.

public class Circle extends Canvas{
    int x;
    int y;
    int rectwidth;
    int rectheight;

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

    public void paint (Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        super.paint(g);
        // draw Ellipse2D.Double
        g2.draw(new Ellipse2D.Double(x, y, rectwidth, rectheight));
        g2.setColor(Color.BLACK);
    }
}

The following is taken from the View class:

Panel container = new Panel();
container.setPreferredSize(new Dimension(400,400));
container.setLayout(new BorderLayout());
Circle circle = new Circle(20,20,200);
container.add(circle, BorderLayout.CENTER);
frame.add(container); // <- this does not draw
frame.add(circle);// <- this draws the circle   
frame.pack();
frame.setVisible(true);

I tried it with FlowLayout, no layout, remove pack(), remove preferredSize, drawing multiple circles on the Frame. Thank you for any answers.


Solution

  • frame.add(container); // <- this does not draw
    frame.add(circle);// <- this draws the circle   
    

    First of all a component can only have a single parent so you can't add the "circle" to the "container" and then to the "frame". The "circle" will be removed from the "container".

    So I will assume you test with only one statement at a time.

    Each component should determine its own preferred size.

    container.setPreferredSize(new Dimension(400,400));
    

    You should NOT be setting the preferred size of the panel. The panel will determine its own preferred size based on the preferred size of components added to the panel.

    The issue is that the "Circle" class does not determine its own preferred size.

    In the constructor you need code like:

    int width = x + rectWidth;
    int height = y + rectHeight;
    setPreferredSize( new Dimension(width, height) );
    

    Now when you add the Circle to the panel, the layout manager of the panel can do its job.

    Or, if you add the Circle to the frame, the layout manager of the content pane can do its job.