Syrrus
Syrrus

Reputation: 79

how to get JPanel with RectangularShape in JPanel to paint

I'm having an issue with drawing RectangularShapes Or Shapes. I need to have this within the actual Panel instead of within the Frame because I need that kind of flexibility. But I keep on getting stuck. I haven't been well trained in GUI with any language so feedback is much appreciated.

Code is below, Please help me find out why this isn't working, and how I can get it to work.

public class GUI_Test 
{
    public static void main(String[] args)
    {
        GUI_Test gui = new GUI_Test();
        gui.tryBasic();
    }


    public void tryBasic()
    {
        JFrame MyFrame = new JFrame();
        MyFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MyFrame.setSize(800, 500);
        MyFrame.setLayout(new BorderLayout());

        // This won't work and can't figure out why!!!!
        // The button appears but not the Ellipse.
        JPanel JP = new JPanel();
        JButton btn3 = new JButton("This is a button");
        JP.add(new MyGUIObject(new Ellipse2D.Double(70, 70, 100, 100), Color.red));
        JP.add(btn3);
        MyFrame.getContentPane().add(JP);

        // This works but I need it in a panel for easier control 
        //MyFrame.add(new MyGUIObject(new Ellipse2D.Double(70, 70, 100, 100), Color.blue));

        // This of course works.
        //MyFrame.getContentPane().add(new MyGUIObject(new Ellipse2D.Double(70, 70, 100, 100), Color.green));

        MyFrame.setVisible(true);

    }
    public class MyGUIObject extends JPanel
    {
        protected RectangularShape RecObj;
        protected Color myColor;    
        public MyGUIObject(RectangularShape SetShape, Color setColor)
        {
            RecObj = SetShape;
            myColor = setColor;
        }
        @Override
        protected void paintComponent(Graphics g)
        {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(myColor);
            g2d.fill(RecObj);
        }
    }
}

Upvotes: 1

Views: 66

Answers (2)

GrowlingBadger
GrowlingBadger

Reputation: 178

How about this:

public class GUI_Test {
    public static void main(String[] args) {
        GUI_Test gui = new GUI_Test();
        gui.tryBasic();
    }

    public void tryBasic() {
        JFrame frame = createFrame();
        JPanel panel = new JPanel(new BorderLayout());
        JButton button = new JButton("This is a button");
        JPanel buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.add(button);
        MyGUIObject guiObject = new MyGUIObject(new Ellipse2D.Double(70, 70, 100, 100), Color.red);
        panel.add(buttonPanel, BorderLayout.PAGE_START);
        panel.add(guiObject,BorderLayout.CENTER);
        frame.getContentPane().add(panel, BorderLayout.CENTER);
        frame.setVisible(true);
    }

    private JFrame createFrame() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 500);
        frame.setLayout(new BorderLayout());
        return frame;
    }

    public class MyGUIObject extends JPanel {
        protected RectangularShape RecObj;
        protected Color myColor;

        public MyGUIObject(RectangularShape SetShape, Color setColor) {
            RecObj = SetShape;
            myColor = setColor;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(myColor);
            g2d.fill(RecObj);
        }
    }
}

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347204

There are three main problems I can see.

  1. You're not calling super.paintComponent from your paintComponent method, this is going to cause some interesting, but nasty paint artefacts
  2. JPanel use a FlowLayout by default, where the JFrame uses a BorderLayout, this is further complicated by...
  3. You don't provide any sizing hints for the MyGUIObject class, so the FlowLayout will use the JPanel's default preferredSize, which is 0x0 when it calculates the layout for the JPanel.

First, call super.paintComponent from your paintComponent method and override the getPreferredSize method

public class MyGUIObject extends JPanel {

    protected RectangularShape RecObj;
    protected Color myColor;

    public MyGUIObject(RectangularShape SetShape, Color setColor) {
        RecObj = SetShape;
        myColor = setColor;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(myColor);
        g2d.fill(RecObj);
    }
}

Next, change the layout that the JPanel is using to something like BorderLayout (although the default FlowLayout will work, BorderLayout will give you a little more control)

JPanel JP = new JPanel(new BorderLayout());
JButton btn3 = new JButton("This is a button");
JP.add(new MyGUIObject(new Ellipse2D.Double(70, 70, 100, 100), Color.red));
JP.add(btn3, BorderLayout.SOUTH);
MyFrame.getContentPane().add(JP);

Have a look at Painting in AWT and Swing, Performing Custom Painting, Laying Out Components Within a Container and How to Use Borders for more details

Upvotes: 2

Related Questions