【问题标题】:JavaFX: Update Label regularly based on TimerTask using StringProperty with ChangeListenerJavaFX:使用 StringProperty 和 ChangeListener 基于 TimerTask 定期更新标签
【发布时间】:2018-05-09 12:37:11
【问题描述】:

我正在尝试使用更改 StringProperty 值的 TimerTask 每秒更新一次标签:

public class RandomString extends TimerTask {

private StringProperty randomString;
private ArrayList<String> strings;
private Random random;

public RandomString(String... str) {
    randomString = new SimpleStringProperty(this, "randomString", "");
    strings = new ArrayList<>(Arrays.asList(str));
    random = new Random();
}

public String getRandomString() {
    return randomString.get();
}

public StringProperty randomStringProperty() {
    return randomString;
}

public void setRandomString(String randomString) {
    this.randomString.set(randomString);
}

@Override
public void run() {
    int i = random.nextInt(strings.size());
    setRandomString(strings.get(i));
}

public void startTimer() {
    new Timer(true).schedule(this, 0, 1000);
}

为了更新标签,我向 StringProperty 添加了一个 ChangeListener,它根据字符串更改标签的文本:

randomString.randomStringProperty().addListener(
            (observable, oldValue, newValue) -> 
                    Platform.runLater(() -> label.setText(newValue)
));

但由于我必须使用 runLater 方法运行此操作,因此标签不会定期更新。如何实现每秒发生一次的更新?

【问题讨论】:

  • 看看这里:*.com/a/16138351/4167500
  • @JKostikiadis 非常感谢,它就像一个魅力 :) 时间轴是一个非常强大的工具

标签: java javafx timertask


【解决方案1】:

对于那些对解决方案感兴趣的人:使用时间线代替 TimerTask 效果很好:

public void startTimer() {
    Timeline timeline = new Timeline();
    timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO, event -> {
        int i = random.nextInt(strings.size());
        setRandomString(strings.get(i));
    }));
    timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1)));
    timeline.setCycleCount(Timeline.INDEFINITE);
    timeline.play();
}

感谢@JKostikiadis 分享这篇文章:https://*.com/a/16138351/4167500

【讨论】:

    【解决方案2】:

    你也可以试试这个。你需要一个 runnable 来让它工作:

       Timer t1 = new Timer();
       private void startTimer() {
        t1.schedule(new TimerTask() {
            @Override
            public void run() {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        label.setText("Testing");
                    }
                });
            }
        }, 0, 1000);
    }
    

    【讨论】: