在一次计时器操作中更新标签两次

时间:2015-12-26 09:48:12

标签: java swing timer thread-sleep

我有一个Dmi类,Swing组件框架和一个标签。

我有Swing计时器。在计时器实现中,我有两个语句在标签中设置文本,有一个时间间隔,但我只能看到最后一个setText操作。

import javax.swing.*;
import java.util.Timer.*;
import java.awt.event.*;
class Dmi implements ActionListener
{

Timer tim;
JFrame frame;
JLabel lbl;
Dmi()
{
    frame=new JFrame("abc");
    lbl=new JLabel("count");
    frame.add(lbl);
    frame.setVisible(true);
    frame.pack();
    tim=new Timer(1000,this);
    tim.start();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) 
{
    Thread th1=new Thread();
    lbl.setText("abc");
    try
    {
        th1.sleep(300); 
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
    lbl.setText("ddd:");

}
public static void main(String[] args) 
{
    new Dmi();  
}
}

1 个答案:

答案 0 :(得分:4)

首先仔细查看Concurrency in SwingHow to use Swing Timers

Swing Timer将在Event Dispatching Thread中生成ActionEvent个,这使得它们非常适合从内部更新UI。

但是,你的代码......

public void actionPerformed(ActionEvent ae) 
{
    Thread th1=new Thread();
    lbl.setText("abc");
    try
    {
        th1.sleep(300); 
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
    lbl.setText("ddd:");

}

阻止事件调度线程(通过使用Thread#sleep),这将阻止EDT处理新的重绘事件或任何其他基于用户的事件,使您的程序看起来好像它已挂起

您将需要设计一个解决方案,该解决方案允许您确定计时器运行的时间并根据该更改状态或可能使用SwingWorker而不是

例如......

import java.awt.EventQueue;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Dmi {

    JFrame frame;
    JLabel lbl;

    Dmi() {
        frame = new JFrame("abc");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lbl = new JLabel("count");
        frame.add(lbl);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        Worker worker = new Worker();
        worker.execute();
    }

    public class Worker extends SwingWorker<String, String> {

        @Override
        protected String doInBackground() throws Exception {
            while (!isCancelled()) {
                Thread.sleep(1000);
                publish("abc");
                Thread.sleep(300);
                publish("def");
            }
            return null;
        }

        @Override
        protected void process(List<String> chunks) {
            lbl.setText(chunks.get(chunks.size() - 1));
        }

    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                Dmi dmi = new Dmi();
            }
        });
    }
}