Reputation: 2760
I have a problem when i'm trying to use a Timer Object and a repaint() when it is called.
Here's my Window Class :
import javax.swing.*;
import java.awt.*;
public class Window extends JFrame{
Panel pan = new Panel();
JPanel container, north,south, west;
JButton ip,print,cancel,ok;
JTextArea timeStep;
JLabel legend;
double temperature=0.0;
public static void main(String[] args) {
new Window();
}
public Window()
{
System.out.println("je suis là");
this.setSize(700,400);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setTitle("Assignment2 - CPU temperature");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container = new JPanel(new BorderLayout());
north = new JPanel();
ip = new JButton ("New");
north.add(ip);
north.add(new JLabel("Time Step: "));
timeStep = new JTextArea("10",1,5);
north.add(timeStep);
print = new JButton ("Print");
north.add(print);
south = new JPanel();
legend = new JLabel("Legends are here");
south.add(legend);
west = new JPanel();
JLabel temp = new JLabel("°C");
west.add(temp);
container.add(north, BorderLayout.NORTH);
container.add(west,BorderLayout.WEST);
container.add(pan, BorderLayout.CENTER);
container.add(south, BorderLayout.SOUTH);
this.setContentPane(container);
this.setVisible(true);
}
}
And Here's my Panel class :
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Panel extends JPanel implements ActionListener {
Timer chrono = new Timer(1000,this);
int i = 0;
int t = 10;
public Panel()
{
super();
chrono.start();
}
public void paintComponent(Graphics g)
{
g.drawLine(20, 20, 20, this.getHeight()-50);
g.drawLine(20, this.getHeight()-50, this.getWidth()-50, this.getHeight()-50);
g.drawLine(20, 20, 15, 35);
g.drawLine(20, 20, 25, 35);
g.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-45);
g.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-55);
g.drawLine(20+t, this.getHeight()-50-i, 20+t, this.getHeight()-50);
}
@Override
public void actionPerformed(ActionEvent e) {
/*i = (int)(50+(20 + (Math.random() * (60 - 20))));
t = t+10;
repaint();
System.out.println("chrono");*/
}
}
Here's how it is like when the repaint() function isn't called :
GUI:
And Finally here's how it looks like when repaint() function is called :
GUI bug:
It seems that all of my JPanels are repainting only once and then everything works...
Any thought?
Upvotes: 1
Views: 155
Reputation: 10623
The problem is that you never paint over what's drawn before. JPanel
by default is supposed to be opaque, meaning that it will draw over its entire area each redraw, freeing the frame to not have to worry about cleaning up that space. However, you're removing that functionality from the JPanel
.
In your paintComponent
method, add this at the top:
super.paintComponent(g);
This will let the JPanel
correctly redraw itself (by calling its own paintComponent
method), so that you can do your drawing over a clean slate.
In response to your comment, the best way to keep the old lines is to keep track of each line to draw, and repaint them all each time. To do that, you would need to replace t
and i
with lists, which would look something like this:
List<Integer> is = new ArrayList<>();
List<Integer> ts = new ArrayList<>();
int lastT = 0;
And then add to those instead of simply setting the value:
int i = (int)(50 + (20 + (Math.random() * (60 - 20))));
lastT += 10;
is.add(i);
ts.add(lastT);
repaint();
And finally, loop over each value:
for(int j = 0; i < is.size() && ts.size(); i++){
int i = is.get(j);
int t = ts.get(j);
g.drawLine(20 + t, this.getHeight() - 50 - i,
20 + t, this.getHeight() - 50);
}
I haven't tested the above code, so it may have some mistakes, but it should be the right idea.
Upvotes: 4