代码之家  ›  专栏  ›  技术社区  ›  Kaes3kuch3n

JavaFX:使用带有ChangeListener的StringProperty根据TimerTask定期更新标签

  •  0
  • Kaes3kuch3n  · 技术社区  · 7 年前

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

    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方法运行此操作,因此标签不会定期更新。如何实现每秒更新一次?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Kaes3kuch3n    7 年前

    对于那些对解决方案感兴趣的人:使用时间线而不是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://stackoverflow.com/a/16138351/4167500

        2
  •  0
  •   zzdhxu    7 年前

    你也可以试试这个。您需要一个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);
    }