user125318 user125318 - 1 month ago 4
Java Question

How does Java repaint() work?

I want to learn java paint so i have created some codes to understand how do java paint and repaint work. Here is 2 code samples what are what are the differences between them? and why does not repaint work?

First code sample (it works)

package com.oguz;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PaintTest3 extends JFrame{
JPanel panel1;
int i = 1;
public PaintTest3() {
panel1 = new JPanel();
JButton btn = new JButton("Button");
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
i++;
Graphics g = panel1.getGraphics();
g.setColor(Color.BLACK);
g.drawLine(10, 10, i * 5, 10);
}
});
add(panel1);
add(btn, BorderLayout.NORTH);
}
public static void main(String args[]){
PaintTest3 pt = new PaintTest3();
pt.setDefaultCloseOperation(EXIT_ON_CLOSE);
pt.setSize(600, 500);
pt.setVisible(true);
}
}


Second code sample (it does not work)

package com.oguz;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PaintTest3 extends JFrame{
private static final long serialVersionUID = -266992942912515861L;
JPanel panel1;
int i = 1;
public PaintTest3() {
panel1 = new JPanel();
JButton btn = new JButton("Button");
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
i++;
repaint();
}
});
add(panel1);
add(btn, BorderLayout.NORTH);
}
@Override
public void paint(Graphics g) {
super.paint(g);
draw(g);
}
public void draw(Graphics g){
g.setColor(Color.BLACK);
g.drawLine(10, 10, i * 5, 10);
}
public static void main(String args[]){
PaintTest3 pt = new PaintTest3();
pt.setDefaultCloseOperation(EXIT_ON_CLOSE);
pt.setSize(600, 500);
pt.setVisible(true);
}
}

Answer

I tried your second version and it works perfectly fine. The only thing I had to change was to make the line further down: g.drawLine(10, 100, i * 5, 100); because it was being drawn behind the button. Ideally if you want to draw in an area then you would extend JPanel with a custom paint and place it below the button.

To explain repaint further - the point of 'repaint' is to tell the window manager that you have changed something that requires the component to be redrawn. The redraw operation will occur sometime later (actually in a different thread) using paint. The window manager might paint once for several repaint calls (if they happen quickly enough). You shouldn't call paint in your own code: you implement it and let the system call it when required.

The problem with your first implementation is that nothing will happen if a paint has to occur without the button being pressed. For example if you resize the window or minimize/maximize it.

So, in summary, your second implementation is correct you just need to position your line correctly and, ideally, draw in a panel rather than a frame.