Reputation: 113
I want to practice paintComponent method. My program is consist of two classes(test and paintClass) in different files. I want to divide the area into 25 squares by drawing lines vertically and horizontally by using paintComponent method. My constructor only has paintComponent now. I know it is not very efficient but I will add buttons, labels and other things in the future so I need to use the program like this. When I run the program I get a nullpointerexception error.Can you help?
EDIT : I changed the page into g and added some lines into code. Still has the same error.
import javax.swing.*;
import java.awt.*;
public class test
{
public static void main(String[] args)
{
JFrame frame = new JFrame("buttons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
paintClass paint = new paintClass();//This line has error.
paint.repaint();//ADDED
frame.add(paint);
frame.pack();
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class paintClass extends JPanel
{
private Graphics g;
private int interval,side,number;
public paintClass()
{
this.repaint();//ADDED
paintComponent(g);//This line has error.
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);//ADDED and has an error.
this.repaint();//ADDED
side = 250;
number = 5;
interval = side / number;
g.drawRect(0,0, side, side);
for(int i = 0; i <= number - 1; i++)
{
for(int j = 0; j <= number - 1; j++)
{
g.drawLine(i * interval, 0, i * interval, side);
}
g.drawLine(0, i * interval, side, i * interval);
}
}
}
Upvotes: 1
Views: 614
Reputation: 347244
First rule of painting in Swing, you don't control the paint process. Swing will paint when and if it wants. The best you can do is provide hints to the system that you would like something updated.
repaint
directly or indirectly from inside any paint method, this will set up a recursive paint cycle which will eventually consume your CPUrepaint
on a component which isn't displayable on the screenFor example
public class paintClass extends JPanel
{
private int interval,side,number;
public paintClass()
{
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
side = 250;
number = 5;
interval = side / number;
g.drawRect(0,0, side, side);
for(int i = 0; i <= number - 1; i++)
{
for(int j = 0; j <= number - 1; j++)
{
g.drawLine(i * interval, 0, i * interval, side);
}
g.drawLine(0, i * interval, side, i * interval);
}
}
}
Upvotes: 1
Reputation: 8348
You are calling paintComponent in the paintClass's constructor with a Graphics object that has not been instantiated. For simple drawing, you shouldn't need to call this method directly - it will be called by the EDT (with the appropriate Graphics object) when necessary (in other words, remove that line and don't hold onto a reference to the Graphics object).
//constructor of Class - note Classnames should start with uppercase
public paintClass(){
//no need to call paintComponent or repaint here
}
You can request a repaint by calling the repaint() method defined by JComponent (the parent class of JPanel). You should also call the parent method
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
//do your custom drawing here, and never call repaint from this method
}
I would recommend, if you have not yet, is to study the Oracle tutorials about Custom painting: http://docs.oracle.com/javase/tutorial/uiswing/painting/
Upvotes: 2
Reputation: 22474
You need to Override
the paintComponent(Graphics g)
not to create one. Also, if you want the paintComponent(...)
to be executed, call repaint()
on that component, do not call paintComponent(...)
directly.
Upvotes: 0
Reputation: 2110
In your class "paintClass", you should instantiate the page var :
public paintClass()
{
page = new Graphics();
paintComponent(page);
}
Upvotes: -2