repaint()函数 - JAVA Swing

时间:2015-12-08 13:54:12

标签: java swing

我在尝试使用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都只重画了一次然后一切正常......

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

问题是你永远不会画出以前绘制的东西。默认情况下,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);
}

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