我在尝试使用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()函数时的样子:

界面:



最后是调用repaint()函数时的样子:

GUI错误:



似乎我所有的JPanels都只重新绘制一次,然后一切正常...

任何想法?

最佳答案

问题在于,您永远都无法绘制之前绘制的内容。默认情况下,JPanel应该是不透明的,这意味着它将在每次重绘时在整个区域上绘制,从而释放了框架,不必担心清理该空间。但是,您正在从JPanel中删除​​该功能。

在您的paintComponent方法中,将此添加到顶部:

super.paintComponent(g);


这将使JPanel正确重绘自身(通过调用其自己的paintComponent方法),以便您可以在干净的板上进行绘制。

根据您的评论,保留旧线条的最佳方法是跟踪要绘制的每条线条,并每次都重新绘制它们。为此,您需要将ti替换为列表,如下所示:

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);
}


我没有测试上面的代码,因此可能会有一些错误,但这应该是正确的想法。

关于java - repaint()函数-JAVA Swing,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34157691/

10-11 01:13