如何在 JavaFX 中延迟 10 秒在 TextArea 中附加文本?
Posted
技术标签:
【中文标题】如何在 JavaFX 中延迟 10 秒在 TextArea 中附加文本?【英文标题】:How to append text in a TextArea by delay of 10 seconds in JavaFX? 【发布时间】:2019-06-07 05:21:41 【问题描述】:我有这个将数据粘贴到TextArea
的函数,我想在DisplayChain
的每次迭代中附加文本,10 秒后(只是一个示例)。我应该使用什么?
这是我的DisplayChain
代码:
public void DisplayChain()
for(int i=0;i<chain.size();i++)
a.appendText("Block: " + i + "\n");
a.appendText("Version: " + chain.get(i).getVersion()+ "\n");
a.appendText("TimeStamp: " + chain.get(i).getTimestamp()+ "\n");
a.appendText("PreviousHash: " + chain.get(i).getPreviousHash()+ "\n");
a.appendText("Hash: " + chain.get(i).getHash()+ "\n");
a.appendText("\n");
【问题讨论】:
您是否正在处理DisplayChain
方法中的迭代?
@thepooran 是的,我想在DisplayChain
上延迟每次迭代
【参考方案1】:
最简单的方法是使用 Thread.sleep 方法,但不能在 JavaFX 应用程序线程中调用它。如果你这样做,你会阻塞应用程序本身:在你的睡眠调用完成之前,不会呈现控件并且不会响应来自鼠标或键盘的用户输入。
这意味着不能从事件处理程序或侦听器调用 Thread.sleep。要解决这个问题,请从一个全新的线程调用 Thread.sleep。
然而,虽然 Thread.sleep 不能在应用程序线程中调用,但 JavaFX 方法的情况正好相反:它们必须从应用程序线程中调用。 Platform.runLater 方法允许您这样做:
Runnable task = () ->
try
for (int i = 0; i < chain.size(); i++)
int index = i;
Platform.runLater(() ->
a.appendText("Block: " + index + "\n");
a.appendText("Version: " + chain.get(index).getVersion()+ "\n");
a.appendText("TimeStamp: " + chain.get(index).getTimestamp()+ "\n");
a.appendText("PreviousHash: " + chain.get(index).getPreviousHash()+ "\n");
a.appendText("Hash: " + chain.get(index).getHash()+ "\n");
a.appendText("\n");
);
Thread.sleep(10000);
catch (InterruptedException e)
e.printStackTrace();
;
new Thread(task).start();
int index = i;
的原因是局部变量不能被其他类读取,例如提供给 Platform.runLater 的匿名 Runnable,除非它们是最终的(或实际上是最终的)。
上面的代码假设chain
集合没有改变。如果在您阅读它时它可能会发生变化,您必须将chain
设为线程安全集合(如ConcurrentLinkedDeque 或CopyOnWriteArrayList),或者自己实现线程安全,这可能比您预期的代码更复杂.
【讨论】:
【参考方案2】:使用Timeline
重复触发appendText
调用以进行单个“循环迭代”:
final Timeline timeline = Timeline();
EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>()
int i = 0;
@Override
public void handle(ActionEvent e)
if (i >= chain.size())
// stop thread, if index exceeds chain size
timeline.stop();
else
// execute a single "loop iteration"
a.appendText("Block: " + i + "\n"
+ "Version: " + chain.get(i).getVersion()+ "\n"
+ "TimeStamp: " + chain.get(i).getTimestamp()+ "\n"
+ "PreviousHash: " + chain.get(i).getPreviousHash()+ "\n"
+ "Hash: " + chain.get(i).getHash()+ "\n"
+ "\n");
i++;
;
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(10), handler));
timeline.setCycleCount(Animation.INDEFINITE); // keep timeline running until handler stops it
timeline.play();
注意:我建议将chain.get(i)
提取到一个局部变量中,以避免多次访问该集合。
【讨论】:
【参考方案3】:你可以申请javafx.application.Platform
:
new Thread ( () ->
try
Thread.sleep ( delayMs ); // 1000 in this case
Platform.runLater ( () ->
...
);
catch ( InterruptedException ie )
).start ( );
【讨论】:
【参考方案4】:如果我理解得很好,你可以添加这一行
Thread.sleep(10000);
【讨论】:
在应用程序线程中休眠会阻止应用程序更新和接收用户输入。以上是关于如何在 JavaFX 中延迟 10 秒在 TextArea 中附加文本?的主要内容,如果未能解决你的问题,请参考以下文章