2015-06-11 84 views
1

我有一个文本区域和保存按钮的GUI。当我按下后者时,文本被保存。这大约需要2秒钟。在保存按钮的过程中,应该获得另一个标题,而不是保存之前和之后。JavaFX和GUI线程:从线程更改按钮文本

这里是我的代码:

saveButton.setText("Saving..."); 
    Util.print("Saving..."); 

    Thread saveIt = new Thread(new Runnable() { 
     @Override public void run() { 
      Platform.runLater(() -> { 
       try { 
        Thread.sleep(2000); 
       } catch (Exception ex) { 
        Util.print(ex); 
       } 
       saveButton.setText("Saved!"); 
       Util.print("Saved!"); 
      }); 
     } 
    }); 
    saveIt.setDaemon(true); 
    saveIt.start(); 

会发生什么:

Saving... 
Saved! 

命令行打印:按下按钮后

以下输出在命令行中产生点击saveButton后,直接点击“保存...”。按saveButton 2秒后,命令行将打印“已保存!”并且按钮标题更改为“已保存!”。

我会期待什么:

命令行输出和按钮标题秀“保存...”后直接我点击保存按钮。 2秒后,标题更改为“已保存!”。

我该如何达到预期的行为?

非常感谢您的帮助。

P.S .:我知道很多人在线程中改变GUI元素都有问题。我已经阅读了关于它的一些关于StackOverflow &的文章,但这对我来说太难了。仅供参考,这里是我的一些尝试,到目前为止,其他任务之间的事情:

Constantly Update UI in Java FX worker thread

Why am I getting java.lang.IllegalStateException "Not on FX application thread" on JavaFX?

javafx, update ui from another thread

http://blog.axxg.de/javafx-ui-thread-update/

回答

2

我不得不把Thread.sleep()方法的一部分了Platform.runLater来从使用Platform.runLater JavaFX的线程调用()处理。看似runLater()的工作量必须尽可能少。

Platform.runLater(() -> { 
    saveButton.setText("Saving..."); 
    Util.print("Saving..."); 
}); 


Thread saveIt = new Thread(new Runnable() { 
    @Override public void run() { 
     try { 
      sleep(2000); 
     } catch (Exception ex) { 
      Util.print(ex); 
     } 
     Platform.runLater(() -> { 
      saveButton.setText("Saved!"); 
      Util.print("Saved!"); 
     }); 
    } 
}); 
saveIt.setDaemon(true); 
saveIt.start(); 
+1

是的!您正在将JavaFX线程休眠。 –

2

尝试包装你的第一的setText到像这样的Platform.runLater:

Platform.runLater(() -> { 
    saveButton.setText("Saving..."); 
}); 

到一个JavaFX UI组件的每次修改都有

+0

它在10个案例中的大约1个中起作用。我已经尝试在示例代码中使用单独的线程进行包装,但也不起作用。也不是如果我使用Thread.join()。 –

+0

谢谢,你帮我找到了正确的答案。 –