paintComponent

Hi

I’m trying to make a kind of UML design software and I was going to use the paintComponent to draw boxes.

However I cannot include paintComponent in a method or using multiple painComponents or calling methods in paintComponents as it says I haven’t declared the Graphics g.

So I thought to use arrays to have multiple elements, but this way everything gets way too complicated, am I using a wrong approach?
Can you help me sort this out?

package graphicdraw;

import javax.swing.*;

public class Main
{
    public static void main(String[] args)
    {
	JFrame f = new JFrame("UMLIDE");
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        draw d = new draw();
	f.add(d);
	f.setSize(800, 250);
	f.setVisible(true);
    }
}
package graphicdraw;

import java.awt.*;
//import java.awt.event.*;
import javax.swing.*;

public class draw extends JPanel
{

    int i;
    int n = 3;
    int[] x = new int[n];
    int[] y = new int[n];
    int[] w = new int[n];
    int[] l = new int[n];
    String[] className = new String[n];

    public draw()
    {
        i = 0;
        x[i] = 25;
        y[i] = 25;
        l[i] = 100;
        w[i] = 30;
        className[0] = "CLASS 1";
        className[1] = "CLASS 2";
        className[2] = "CLASS 3";

        for(i=1; i<n; i++)
        {
        x[i]=x[i-1]+110;
        y[i] = 25;
        l[i] = 100;
        w[i] = 30;
        }
    }
    
    public draw(int $x, int $y, int $l, int $w)
    {
        i = 0;
        x[i] = $x;
        y[i] = $y;
        l[i] = $l;
        w[i] = $w;
    }

    @Override
    public void paintComponent(Graphics g)
    {
	super.paintComponent(g);
	this.setBackground(Color.WHITE);
        
	g.setColor(Color.BLACK);

        for(i=0; i<n; i++)
        {
	g.drawRect(x[i], y[i], l[i], w[i]); //Class
        g.drawRect(x[i], y[i]+w[i], l[i], w[i]); //Variables
        g.drawRect(x[i], y[i]+w[i]*2, l[i], w[i]); //Methods
        g.drawString(className[i], x[i]+15, y[i]+15);
        g.drawString("VARIABLES", x[i]+15, y[i]+w[i]+15);
        g.drawString("METHODS", x[i]+15, y[i]+w[i]*2+15);
        }
    }  
}

You don’t call paintComponent directly, rather you call repaint() and swing will take care of calling paintComponent.

If you want to perform drawing in a separate function make sure to call it from within paintComponent and pass the Graphics object to your other function.

I solved that by using paint(Graphics g) instead of paintComponent(Graphics g).

Add the paint to a class that extends JPanel, then add the class to the frame.
Then you can call paint by using repaint(); :slight_smile:
Swing will take care of the Graphics object

Thanks guys,

what I was doing wrong is not sending (Graphics g) to the method I was calling.


@Override
    public void paintComponent(Graphics g)
    {
	super.paintComponent(g);
	this.setBackground(Color.WHITE);
        
	g.setColor(Color.BLACK);

        drawBox(g);

        for(i=0; i<n-1; i++) // change for the purpose of testing, so paintComponent draws only the first and second box
        {
	g.drawRect(x[i], y[i], l[i], w[i]); //Class
        g.drawRect(x[i], y[i]+w[i], l[i], w[i]); //Variables
        g.drawRect(x[i], y[i]+w[i]*2, l[i], w[i]); //Methods
        g.drawString(className[i], x[i]+15, y[i]+15);
        g.drawString("VARIABLES", x[i]+15, y[i]+w[i]+15);
        g.drawString("METHODS", x[i]+15, y[i]+w[i]*2+15);
        }
    }

    public void drawBox(Graphics g)
    {
        i=2; // this method draws only the third box
        g.drawRect(x[i], y[i], l[i], w[i]); //Class
        g.drawRect(x[i], y[i]+w[i], l[i], w[i]); //Variables
        g.drawRect(x[i], y[i]+w[i]*2, l[i], w[i]); //Methods
        g.drawString(className[i], x[i]+15, y[i]+15);
        g.drawString("VARIABLES", x[i]+15, y[i]+w[i]+15);
        g.drawString("METHODS", x[i]+15, y[i]+w[i]*2+15);
        repaint();  //this is optional if called in this way
    }

Slightly off topic, there is no point to extend JPanel as it is only used as a container for other components. JComponent is the most appropriate class to draw into and since JPanel extends JComponent, there should be no change to your code at all.

I still don’t know the difference between paint and paintComponent. I also have no idea what JComponent is.

javax.swing.JComponent is the Swing version of java.awt.Component. AWT components only have “paint” and that is where everything is drawn. In Swing, “paint” doesn’t draw anything, instead it calls 3 methods: “paintComponent”, “paintBorder”, and “paintChildren”. Instead of overriding “paint”, it is recommended to override “paintComponent” if you extend any Swing component (which all start with a “J”). You should read this article about painting in AWT and Swing to get a grasp on how the mechanics work. You should also look at the Java Swing API and familiarize yourself with it.

@Frann
O_o ?