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

标签 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();  
}
}

最佳答案

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

Swing Timer 将在事件调度线程中生成 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();
            }
        });
    }
}

关于java - 在一次定时器操作中更新标签两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34470183/

相关文章:

Java SSH 工具 : pause download with SftpClient

java - 使用 MouseListener 选择网格中的一系列单元格

java - 在 Java 中创建 JTable

c++ - 适用于 Linux 的 Cpp 定时器

java - 如何检查是否在特定时限内收到蓝牙响应?

java - 为什么 Bounded 类型参数出现 "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to"错误而不是 Formal 类型参数?

java - Java图形画线性能问题

java - log4j 2配置: appenderRef. xyz.ref?

java - JFrame 中的多个 JPanel

java - 定时任务不运行