我在尝试使用Timer对象和repaint()时遇到问题。
这是我的窗口类:
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);
}
}
这是我的Panel类:
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");*/
}
}
以下是未调用repaint()函数时的情况:
GUI:
最后,这里是调用repaint()函数时的样子:
GUI bug:
似乎我的所有JPanel都只重画了一次然后一切正常......
有什么想法吗?
答案 0 :(得分:4)
问题是你永远不会画出以前绘制的东西。默认情况下,JPanel
应该是不透明的,这意味着它将在每次重绘时绘制整个区域,释放框架而不必担心清理该空间。但是,您要从JPanel
删除该功能。
在paintComponent
方法中,将其添加到顶部:
super.paintComponent(g);
这会让JPanel
正确地重绘(通过调用自己的paintComponent
方法),这样你就可以在一个干净的平板上进行绘图。
在回复您的评论时,保留旧线条的最佳方法是跟踪要绘制的每一条线,并每次重新绘制它们。为此,您需要将t
和i
替换为列表,如下所示:
List<Integer> is = new ArrayList<>();
List<Integer> ts = new ArrayList<>();
int lastT = 0;
然后添加到那些而不是简单地设置值:
int i = (int)(50 + (20 + (Math.random() * (60 - 20))));
lastT += 10;
is.add(i);
ts.add(lastT);
repaint();
最后,循环遍历每个值:
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);
}
我还没有测试过上面的代码,所以可能会有一些错误,但这应该是正确的想法。