2

我有一个 JFrame ,它有一个 JPanel 和一个 JButton 。JFrame 设置为 BorderLayout ,我希望我的代码在单击按钮后每 500 毫秒重新绘制一次面板。但即使设置进入循环,框架也不会重新绘制。

这是单击按钮时我写的内容

public void actionPerformed(ActionEvent e) {
    while(true){
        try {
            frame.repaint(); // does not repaint
            Thread.sleep(500);
        } catch (InterruptedException exp) {
            exp.printStackTrace();
        }
    }
}

这用于设置:

public void go() {
    b.addActionListener(new ButtonListener()); // b is the JButton
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // frame is the JFrame
    frame.setLayout(new BorderLayout());
    frame.add(BorderLayout.CENTER, p); // p is a MyPanel
    frame.add(BorderLayout.SOUTH, b);
    frame.setSize(300, 300);
    frame.setVisible(true);

}

class MyPanel extends JPanel { // p is an instance of this MyPanel class

    public void paintComponent(Graphics gr) {
        gr.fillRect(0, 0, this.getWidth(), this.getHeight());

        int r, g, b, x, y;
        r = (int) (Math.random() * 256);
        g = (int) (Math.random() * 256);
        b = (int) (Math.random() * 256);
        x = (int) (Math.random() * (this.getWidth() - 15 ));
        y = (int) (Math.random() * (this.getHeight() - 15));

        Color customColor = new Color(r, g, b);
        gr.setColor(customColor);
        gr.fillOval(x, y, 30, 30);
    }
}
4

2 回答 2

3

ActionListener包含 2 个用于阻止 Swing 应用程序的可靠机制 - 无限循环和Thread.sleep调用。改用摇摆计时器

Timer timer = new Timer(500, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        frame.repaint();
    }
});
timer.setRepeats(false);
timer.start();
于 2013-10-07T15:28:30.347 回答
3

从侦听器执行的代码在事件调度线程 (EDT)上执行,并且 Thread.sleep() 导致 EDT 休眠,因此 GUI 永远无法重新绘制自身。不要使用 Thread.sleep.()。

而是使用Swing Timer

于 2013-10-07T15:28:49.950 回答