Search code examples
javagraphicsjpanelgraphics2d

How to draw Graphics2D on JPanel which is inside another JPanel?


I would like to create 4 JPanels, draw a white rectangular on each and then put them inside one, big JPanel. Big JPanel is inside the main frame.

However, the following code does not work. Please, tell me, how to fix this problem?

import javax.swing.*;
import java.awt.Graphics;

import java.io.*;
import java.net.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.io.IOException;

public class Main extends JFrame
{

public void GUI () {
    setBounds(0, 0, 480, 960);
    addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent we){

            System.exit(0);
            }
        });
        setMinimumSize(new Dimension(480, 960));
        setResizable(false);

        JPanel mainPanel = new JPanel();
        GridLayout GL = new GridLayout(4,0);
        mainPanel.setLayout(GL);

    JPanel panel1 = new MyCanvas();
    JPanel panel2 = new MyCanvas();
    JPanel panel3 = new MyCanvas();
    JPanel panel4 = new MyCanvas();

    mainPanel.add(panel1);
    mainPanel.add(panel2);
    mainPanel.add(panel3);
    mainPanel.add(panel4);

    add(mainPanel);

    setVisible(true);
}

public static void main(String args[]) throws IOException
{
    new Main().GUI();
}

class MyCanvas extends JPanel {

    public void drawCanvas(Graphics g) {

        super.paintComponent( g ); // call superclass's paintComponent  

        Graphics2D g2 = ( Graphics2D ) g; // cast g to Graphics2D  

        g2.setColor(Color.WHITE);

        double x = 100;
        double y = 100;
        double width = x + 200;
        double height = y + 50;

        g2.fillRect(50, 50, 380, 200);
    }
    }
}

Solution

  • What is this supposed to do?:

    public void drawCanvas(Graphics g) {
      ....
    }
    

    This method overrides no JPanel drawing method and so will not routinely get called when the JVM decides to paint your MyCanvas JPanel.

    I think that instead you want to override the class's paintComponent(...) method which can easily be done by simply renaming your method to paintComponent(...). If/when you do this, don't forget to use the @Override annotation to be sure that you're overriding the method with the correct signature. You'll also want to change the method's access specifier to protected, not public.

    Next you'll want to do something with those double variables that you're creating.