无法刷新JFrame

时间:2014-07-21 11:13:44

标签: java multithreading swing timer event-dispatch-thread

我有一个简单的JFrame,其中包含JButtonJLabel

public class Frame extends JFrame {
    public Frame() {
        initComponents();
        this.frameExample = new JFrameExample(jLabel1,jPanel1);
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        //this method only place the button and the label to the frame, it is auto-genereted by Netbeans tool.
    }

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
        frameExample.count();
    }

    public static void main(String args[]) {
        new Frame().setVisible(true);
    }

    JFrameExample frameExample;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
}

我有一个简单的类,它通过构造函数获取label对象,并使用count()方法为标签设置一些值。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class JFrameExample {
    public JFrameExample(JLabel label, JPanel panel) {
        this.label = label;
        this.panel = panel;

        setFrameRefreshTimer();
    }

    public void setFrameRefreshTimer() {
        frameTimer = new Timer (100,new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                label.revalidate();
                label.repaint(); 
                panel.revalidate();
                panel.repaint();  
                System.out.println(label.getText());//doesn't print anything
                }
            });
    }

    public void count() {
        frameTimer.start();

        for (int i = 0; i <= 10; i++) {
            label.setText(i + "");

            try {
                Thread.sleep(500);
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }

        frameTimer.stop();

    }
    private JLabel label;
    private JPanel panel;
    private Timer frameTimer;
}

问题是,我希望在count()方法调用label的{​​{1}}方法时看到数字。但框架不刷新。最后我只看到号码setText()。我没有看到其他数字。

我使用了计时器,但没有用。我使用计时器错了吗?还有其他解决方案吗?我想过10但是我无法让它发挥作用。如果有人能帮我解决这个问题,我将不胜感激。

注意:我使用此示例简化了我的问题,因此包含更改构造函数参数或类似内容的解决方案无法为我提供解决方案。

2 个答案:

答案 0 :(得分:2)

使用setRepeat(true)方法重复计时器,并在stop()方法中调用actionPerformed()方法重复10次后中断循环。

示例代码:

private int counter = 0;
private Timer timer;
...

timer = new javax.swing.Timer(500, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        counter++;
        if(counter==10){
            timer.stop();
        }else{
            label.setText(counter + "");  
        }
    }
});
timer.setRepeats(true);
timer.start();

注意:

请暂时使用Thread.sleep()挂起整个swing应用程序,而不是尝试使用最适合swing应用程序的Swing Timer

了解更多How to Use Swing Timers

答案 1 :(得分:0)

我找到了另一个解决方案,也许这个答案可以帮助其他人。

我使用Thread代替Timer

使用此方法更改方法jButton1MouseClicked()

private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
    thread = new Thread() {
          public void run() {
              frameExample.count(thread); //sent the thread to close it.
          }
        };
    thread.start();
}

稍微更改方法count以关闭线程。

public void count(Thread thread) {
       for (int i = 0; i <= 10; i++) {
            label.setText(i + "");

            try {
                Thread.sleep(500);
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }

       thread.stop();
    }

通过这些更改,我可以看到label的计数。而且您无需从label.setText(i + "");致电Timer