如何更新标签盒的Java FX每2秒?(How to update the label box ev

2019-08-31 16:21发布

我试图模拟一个应用程序的GUI基本恒温。

我想更新标签框值每2秒用新的温度值。

例如,我的INTIAL温度将直到75每2秒被显示为68度和更新,以69至70,等等。

这是一段代码,我用Java FX中写道。 controlpanel是TE形式,其中所述标签盒的存在的对象。 它仅更新最终值75。它不更新,每2秒。 我已经写了一个方法停顿造成2秒延迟。 所有标签都与他们最后的值更新,但每2秒没有更新。 当我调试,我可以看到,值增加了一个每2秒。 此代码是写在按钮onClick事件

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    int i=0;
    Timer asd = new Timer(1000,null);

    asd.setDelay(1000);

    while(i < 10)
    {
         jTextField1.setText(Integer.toString(i));
         i++;

         asd.start();
    }
 }  

Answer 1:

为了解决使用定时器,你需要实现你的任务TimerTask与您的代码,并使用Timer#scheduleAtFixedRate方法重复运行的代码:

Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            System.out.print("I would be called every 2 seconds");
        }
    }, 0, 2000);

还要注意,调用任何UI操作必须Swing的UI线程(或如果您使用JavaFX FX UI线程)来完成:

private int i = 0;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    jTextField1.setText(Integer.toString(i++));
                }
            });
        }
    }, 0, 2000);
}

在JavaFX的情况下,你需要就不是一个秋千“FX UI线程”更新外汇管制。 为了实现这一目标使用javafx.application.Platform#runLater方法代替SwingUtilities



Answer 2:

这里是使用一个JavaFX动画时间线,而不是一个定时器的替代解决方案。

我喜欢这样的解决方案,因为动画框架确保一切都发生了JavaFX应用程序线程,所以你不必担心线程问题。

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Random;

public class ThermostatApp extends Application {
  @Override public void start(final Stage stage) throws Exception {
    final Thermostat       thermostat       = new Thermostat();
    final TemperatureLabel temperatureLabel = new TemperatureLabel(thermostat);

    VBox layout = new VBox(10);
    layout.getChildren().addAll(temperatureLabel);
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 20; -fx-font-size: 20;");

    stage.setScene(new Scene(layout));
    stage.show();
  }

  public static void main(String[] args) throws Exception {
    launch(args);
  }
}

class TemperatureLabel extends Label {
  public TemperatureLabel(final Thermostat thermostat) {
    textProperty().bind(
      Bindings.format(
        "%3d \u00B0F",
        thermostat.temperatureProperty()
      )
    );
  }
}

class Thermostat {
  private static final Duration PROBE_FREQUENCY = Duration.seconds(2);

  private final ReadOnlyIntegerWrapper temperature;
  private final TemperatureProbe       probe;
  private final Timeline               timeline;

  public ReadOnlyIntegerProperty temperatureProperty() {
    return temperature.getReadOnlyProperty();
  }

  public Thermostat() {
    probe       = new TemperatureProbe();
    temperature = new ReadOnlyIntegerWrapper(probe.readTemperature());

    timeline = new Timeline(
        new KeyFrame(
          Duration.ZERO,
          new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              temperature.set(probe.readTemperature());
            }
          }
        ),
        new KeyFrame(
          PROBE_FREQUENCY
        )
    );
    timeline.setCycleCount(Timeline.INDEFINITE);
    timeline.play();
  }
}

class TemperatureProbe {
  private static final Random random = new Random();

  public int readTemperature() {
    return 72 + random.nextInt(6);
  }
}

该解决方案是基于从倒数计时器的解决方案: JavaFX的:如何绑定两个值?



Answer 3:

呼唤Platform.runLater为我工作:

Platform.runLater(new Runnable() {

    @Override
    public void run() {

    }
});


文章来源: How to update the label box every 2 seconds in java fx?