【问题标题】:updating gui from thread(another class)从线程更新 gui(另一个类)
【发布时间】:2016-04-05 03:24:03
【问题描述】:

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

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

如何使用秒表 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"))
         {

         }

      }     
   }

班级秒表

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);

    }
}

我还有一个包含 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);
        }
    });

}

}

【问题讨论】:

    标签: java multithreading swing java-threads


    【解决方案1】:

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

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

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

    一个更简单的解决方案可能是使用 Swing Timer 而不是 Thread,因为 Swing Timer 在 EDT 的上下文中执行其通知

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

    【讨论】:

    • 对于这个练习,我必须创建一个秒表。更新时间的线程。并使用 java swing 组件。我现在已经删除了 Gui 类中的 SwingUtilities.invokeLater(new Runnable()。你建议我做什么?
    • 放回去。我推荐一个观察者模式,所以每次你的计时器更新时,你都会通知需要更新 UI 的观察者
    猜你喜欢
    • 2015-05-10
    • 2020-07-13
    相关资源
    最近更新 更多