栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java Timer-使用Platform.runLater更新标签

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java Timer-使用Platform.runLater更新标签

Runnable
传递给
Platform#runLater(Runnable)
包含一个无限循环。这意味着您在 JavaFX Application
Thread

上执行了无限循环,这就是UI变得无响应的原因。如果FX线程不能自由执行其工作,则无法处理用户生成的事件,并且无法安排渲染“脉冲”。后一点就是为什么即使您
setText(...)
不断调用UI也不更新。

如果要继续使用当前方法,解决方法是

for(;;)
Runnable
实现中删除循环。您将设置为
TimerTask
每毫秒执行一次,这意味着您要做的就是计算新状态并为每次执行设置一次标签。换句话说,该
run()
方法已经“循环”。例如:

TimerTask task = new TimerTask() {    @Override public void run() {        Platform.runLater(() -> { // calculate new state... // update labels... // return (no loop!)        });    }};

也就是说,没有理由为此使用后台线程。我建议改用JavaFX提供的动画API。它是异步的,但在FX线程上执行,因此更易于实现和推理-
使用多个线程总是更复杂。要执行与当前操作类似的操作,可以使用

Timeline
PauseTransition
代替
java.util.Timer
。在JavaFX的周期性后台任务
Q&A给出了使用动画用于此目的的一些很好的例子。

就个人而言,我将使用

AnimationTimer
来实现秒表。这是一个例子:

import java.util.concurrent.TimeUnit;import javafx.animation.AnimationTimer;import javafx.beans.property.ReadOnlyBooleanProperty;import javafx.beans.property.ReadOnlyBooleanWrapper;import javafx.beans.property.ReadOnlyLongProperty;import javafx.beans.property.ReadOnlyLongWrapper;public class Stopwatch {  private static long toMillis(long nanos) {    return TimeUnit.NANOSECONDS.toMillis(nanos);  }  // value is in milliseconds  private final ReadonlyLongWrapper elapsedTime = new ReadonlyLongWrapper(this, "elapsedTime");  private void setElapsedTime(long elapsedTime) { this.elapsedTime.set(elapsedTime); }  public final long getElapsedTime() { return elapsedTime.get(); }  public final ReadonlyLongProperty elapsedTimeProperty() { return elapsedTime.getReadonlyProperty(); }  private final ReadonlyBooleanWrapper running = new ReadonlyBooleanWrapper(this, "running");  private void setRunning(boolean running) { this.running.set(running); }  public final boolean isRunning() { return running.get(); }  public final ReadonlyBooleanProperty runningProperty() { return running.getReadonlyProperty(); }  private final Timer timer = new Timer();  public void start() {    if (!isRunning()) {      timer.start();      setRunning(true);    }  }  public void stop() {    if (isRunning()) {      timer.pause();      setRunning(false);    }  }  public void reset() {    timer.stopAndReset();    setElapsedTime(0);    setRunning(false);  }  private class Timer extends AnimationTimer {    private long originTime = Long.MIN_VALUE;    private long pauseTime = Long.MIN_VALUE;    private boolean pausing;    @Override    public void handle(long now) {      if (pausing) {        pauseTime = toMillis(now);        pausing = false;        stop();      } else {        if (originTime == Long.MIN_VALUE) {          originTime = toMillis(now);        } else if (pauseTime != Long.MIN_VALUE) {          originTime += toMillis(now) - pauseTime;          pauseTime = Long.MIN_VALUE;        }        setElapsedTime(toMillis(now) - originTime);      }    }    @Override    public void start() {      pausing = false;      super.start();    }    void pause() {      if (originTime != Long.MIN_VALUE) {        pausing = true;      } else {        stop();      }    }    void stopAndReset() {      stop();      originTime = Long.MIN_VALUE;      pauseTime = Long.MIN_VALUE;      pausing = false;    }  }}

警告:

AnimationTimer
运行
Stopwatch
实例时,无法进行垃圾回收。

上面提供了一个属性,

elapsedTime
表示经过的时间(以毫秒为单位)。根据该值,您可以计算自秒表启动以来经过的天,小时,分钟,秒和毫秒的数量。您只需收听属性并在属性更改时更新UI。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/398323.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号