如何更新线程中的JFrame标签? - Java

时间:2010-11-22 21:29:17

标签: java user-interface jframe

我已经尝试了很多,但似乎无法让它发挥作用。

我被告知在下面的例子中使用EDT。

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //  Modify the GUI here
        }
});

我已经阅读了很多这个主题但仍然不明白。我得到的是一个线程,但.invokeLater对我来说仍然没有意义。老实说,如果你能 详细解释 ,这将是一个很大的帮助!

计划目标:获取随机生成的密钥,该密钥每秒都会不断创建,以便在GUI中自动更新。

5 个答案:

答案 0 :(得分:4)

所以有一个EDT(Event Dispatch Thread)。屏幕上显示的所有操作均由EDT执行。每个Swing应用程序只有一个EDT。

你在某个任意线程中,你想通过该线程更新GUI?就像我说的每个swing应用程序只有一个EDT,所以你必须告诉EDT显示标签(或你想要的任何上下文)。

这里的想法是,你将这个Runnable推送到EDT拉出的队列中。最终,当完成之前的所有其他操作时,EDT将处理您的runnable。

答案 1 :(得分:2)

我建议你拿到这本书Filthy Rich Clients。有一章他们会详细解释Swing的线程模型。

基本上在Swing中,任何修改GUI的代码都应该在Event Dispatcher Thread中执行。您在那里使用的SwingUtilities类为您提供了一种将事件发布到事件队列的简单方法,然后由EDT调度。这就是invokeLater方法的作用,它需要new Runnable()作为参数,最终在EDT上执行。

从书中可以看出:

  

invokeLater()实现需要   关心创建和排队特殊   包含Runnable的事件。这个   事件在EDT中处理   订单收到了,就像任何一样   其他事件。当它到来的时候,它   通过运行来调度   Runnable的run()方法。

答案 2 :(得分:0)

如果您要做的就是按照已知的时间表更新UI,请尝试以下操作。这假定JFrame是您希望每1秒更新一次的组件。

private static final int WAIT_LENGTH = 1000; // 1 second
private JFrame frame = new JFrame();

// Thread will update the UI (via updateUI() call) about every 1 second
class UIUpdater extends Thread {
  @Override
  void run() {
    while (true) {
      try {
        // Update variables here
      }
      catch (Exception e) {
        System.out.println("Error: " + e);
      }
      finally {
        frame.repaint();
        Thread.sleep(WAIT_LENGTH);
      }
    }
  }
}

开始这个帖子:

UIUpdater t = new UIUpdater();
t.start();

答案 3 :(得分:0)

这是所有GUI编程中非常常见的元素。您有一个线程可以处理绘制GUI,获取输入和运行回调。如果另一个线程试图更改GUI相关对象,它将与GUI线程冲突。比方说,例如,它是绘制内容的一半,并且您从不同的线程更改颜色。

所有invokeLater都会为GUI线程排队等待运行。通过“稍后”它几乎立即运行,但当前线程不必等待它。 GUI线程可能正在进行绘制或等待回调,这将延迟执行您提供的代码。

答案 4 :(得分:0)

需要成为会员,以便我们可以更改它并仍然使用内部类

protected long secret=0;

...这需要在您的代码中某处运行...

JFrame f = new JFrame("foo");
new Thread(){
        public void run() {
            for(;;){
                try { 
                    sleep(1000);
                } catch Interrupted (Exception ix){ 
                    return;
                }
                // TODO update your secret key here
                // please don't use random()

                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        f.setTitle("secret "+x);
                    }
                });
            }
        }
   }).start();

...

只有从EDT更新Swing才能正确绘制。

当你在EDT(在事件处理程序中运行代码)时,你可以调用paintImmediately(),如果你真的必须。