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

Update label twice in one timer operation

我有一个 class 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();  
}
}

先仔细看看 Concurrency in Swing and How to use Swing Timers

Swing Timer 将在事件调度线程内生成 ActionEvents,这使得它们非常适合从内部更新 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();
            }
        });
    }
}