Assaf
Assaf

Reputation: 1124

Java - Drawing Shapes with paintComponent and Polymorphism

I have an assignment in which I have to draw 6 shapes on the same Panel. I have tried several things, but I couldn't find a way to draw the Shapes on the same panel, but only on diffrent Panels.

I have classes for the Shapes:

public abstract class MyShape extends JPanel
public abstract class MyBoundedShape extends MyShape
public class MyOval extends MyBoundedShape
public class MyRectangle extends MyBoundedShape
public class MyLine  extends MyShape

In these classes I have not written a paintComponent Method, but I have written it in a diffreent class, which recieves an Array of Shapes as an attribute:

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class DrawingShapes extends JPanel implements Cloneable{
    private  ArrayList<MyShape> Shapes;
    public DrawingShapes(ArrayList<MyShape> Shapes){
        this.Shapes=Shapes;
        initilizePaintComponent(); //draws a frame for the paintComponent
    }


    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);

        for (int i = 0; i <Shapes.size(); i++) {
            g.setColor(Shapes.get(i).get_color());
            if (Shapes.get(i) instanceof MyRectangle){
                if (((MyRectangle) Shapes.get(i)).get_isFilled()){
                    g.fillRect(Shapes.get(i).get_x1(),Shapes.get(i).get_y1(),
                            Shapes.get(i).get_width(),Shapes.get(i).get_height());
                }
                else
                    g.drawRect(Shapes.get(i).get_x1(), Shapes.get(i).get_y1(),
                            Shapes.get(i).get_width(), Shapes.get(i).get_height());
            }
            if (Shapes.get(i) instanceof MyOval){
                if (((MyRectangle) Shapes.get(i)).get_isFilled()){
                    g.fillOval(Shapes.get(i).get_x1(),Shapes.get(i).get_y1(),
                            Shapes.get(i).get_width(),Shapes.get(i).get_height());
                }
                else
                    g.drawOval(Shapes.get(i).get_x1(), Shapes.get(i).get_y1(),
                            Shapes.get(i).get_width(), Shapes.get(i).get_height());

            }
            else
                g.drawLine(Shapes.get(i).get_x1(), Shapes.get(i).get_y1(),
                        Shapes.get(i).get_width(), Shapes.get(i).get_height());

        }

    }
    public void initilizePaintComponent(){
        JFrame frame = new JFrame("Shapes");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        for (int i = 0; i < Shapes.size(); i++) {
            frame.add(Shapes.get(i));
            frame.setVisible(true);

        }

    }

}

My Problem is that the paintComponent method does not work - The program does not draw a single shape.

After running the program I get an empty Frame named "Shape" - The frame does work, but without Shapes.

Why doesn't the paintComponent work?

Thanks!

Upvotes: 0

Views: 1062

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

This:

public void initilizePaintComponent(){
    JFrame frame = new JFrame("Shapes");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400,400);
    for (int i = 0; i < Shapes.size(); i++) {
        frame.add(Shapes.get(i));
        frame.setVisible(true);
    }
}

ignores the layout manager that JFrame (and all top-level windows) uses by default, BorderLayout. While you may be adding Shapes.size() components to the JFrame, only the last one is visible, since by adding them in a default fashion, the BorderLayout covers all previously added components with the one added last.

Possible Solutions:

  • Use only one drawing JPanel and override its paintComponent method.
  • Add only this one single drawing JPanel to the BorderLayout.CENTER (default position) of your JFrame
  • Make your MyShape class a non-GUI non-component logical class, one with code that allows it to be drawn by the single drawing JPanel above.
  • Give this class a method, say public void draw(Graphics g) that the drawing JPanel will call within its paintComponent
  • Have the drawing JPanel iterate through a List of MyShape objects in a for-loop within its paintComponent method, calling the draw(g) method within the loop.

For more detail to this answer, do consider creating and posting a valid MCVE program with your question.

Upvotes: 2

Related Questions