从线程更新 gui(另一个 class)

updating gui from thread(another class)

我有一个class叫贵。这是我放置所有标签和按钮的地方。 它还包含一个button.addactionlistener。 当按下按钮时,它会启动另一个线程(秒表)。 这是秒表进入一个循环,该循环在 while 循环中不断更新 ms、sec、min。

秒表是另一个 class 文件。秒表包含毫秒、秒、分钟。

如何使用秒表 ms、sec、min 更新 gui 标签?

public class Gui {

JFrame swFrame = new JFrame("Stopwatch");
Stopwatch sw = new Stopwatch();
Thread t1 = new Thread(sw);
private JPanel p;
private JButton b1;
private JButton b2;
private JButton b3;
private JLabel l1;
private JLabel l2;


public Gui()
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {

            swFrame.setSize(500,400);
            swFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            p = new JPanel();

            b1 = new JButton("StartStop");
            b2 = new JButton("LapTime");
            b3 = new JButton("Reset");

            l1 = new JLabel("bla");
            l2 = new JLabel("blala");

            p.add(b1);
            p.add(b2);
            p.add(b3);
            p.add(l1);
            p.add(l2);

            swFrame.add(p);
            b1.setActionCommand("StartStop");
            b2.setActionCommand("LapTime");
            b3.setActionCommand("Reset");
            b1.addActionListener(new ButtonClickListener());
            b2.addActionListener(new ButtonClickListener());
            b3.addActionListener(new ButtonClickListener());

        }
    });
}

private class ButtonClickListener implements ActionListener
{
      public void actionPerformed(ActionEvent e) 
      {
         String command = e.getActionCommand();  
         if( command.equals( "StartStop" ))
         {
            if(t1.isAlive())
            {
                t1.interrupt();
            }
            else
            {
                t1.start();
                !!!//How to update the jlabel from the moment t1.starts?!!!!
            }
         }
         else if( command.equals( "LapTime" ) )
         {
            l2.setText("Submit Button clicked."); 
         }
         else if(command.equals("Reset"))
         {

         }

      }     
   }

class秒表

public class Stopwatch implements Runnable 
{

private int min;
private int sec;
private long ms;
Timer timerSW = new Timer();
JLabel l1;


public void run()
{
    ms = System.currentTimeMillis();



    while(!Thread.currentThread().isInterrupted())
    {
        int seconds = (int) (ms / 1000) % 60 ;
        int minutes = (int) ((ms / (1000*60)) % 60);

    }
}

我还有一个程序 class,其中包含一个 main 方法。这个叫Gui.

public class Program {

public static void main(String[] args) 
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            Gui gui = new Gui();
            gui.swFrame.setVisible(true);
        }
    });

}

}

How do I update the gui label with the stopwatch ms,sec,min?

请注意,Swing 不是线程安全的,您不应在事件调度线程的上下文之外修改它的状态。

一种方法是使用 Observer Pattern,您的计时器会触发 UI 可以响应的更新。

一个更简单的解决方案可能是在 Thread 上使用 Swing Timer,因为 Swing Timer 在 EDT

的上下文中执行其通知

考虑查看 Concurrency in Swing and How to use Swing Timers 了解更多详情