How to update the label box every 2 seconds in java fx?

前端 未结 3 614
故里飘歌
故里飘歌 2020-11-27 19:58

I\'m trying to simulate a basic thermostat in an application GUI.

I want to update a label box value every 2 secs with the new temperature value.

For example

3条回答
  •  孤城傲影
    2020-11-27 20:24

    Here is an alternate solution which uses a JavaFX animation Timeline instead of a Timer.

    I like this solution because the animation framework ensures that everything happens on the JavaFX application thread, so you don't need to worry about threading issues.

    temperatureprobe

    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() {
                @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);
      }
    }
    

    The solution is based upon the countdown timer solution from: JavaFX: How to bind two values?

提交回复
热议问题