Displaying changing values in JavaFx Label

后端 未结 4 999
一生所求
一生所求 2020-11-30 05:10

In JavaFX, how can I display values which continuously change with time using \"label\" ?

相关标签:
4条回答
  • 2020-11-30 05:25

    I like Sebastian's binding answer.

    For variety, here is another sample of modifying a label text based upon time. The sample displays a digital clock readout in a label whose text changes each second using an Timeline.

    import java.io.IOException;
    import java.net.URL;
    import javafx.animation.*;
    import javafx.event.*;
    import javafx.scene.control.Label;
    import javafx.util.Duration;
    
    import java.util.Calendar;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class DigitalClockSample extends Application {
      public static void main(String[] args) { launch(args); }
      @Override public void start(Stage stage) throws IOException {
        stage.setScene(new Scene(new DigitalClock(), 100, 50));
        stage.show();
      }
    }
    
    /**
     * Creates a digital clock display as a simple label.
     * Format of the clock display is hh:mm:ss aa, where:
     * hh Hour in am/pm (1-12)
     * mm Minute in hour
     * ss Second in minute
     * aa Am/pm marker
     * Time is the system time for the local timezone.
     */
    class DigitalClock extends Label {
      public DigitalClock() {
        bindToTime();
      }
    
      // the digital clock updates once a second.
      private void bindToTime() {
        Timeline timeline = new Timeline(
          new KeyFrame(Duration.seconds(0),
            new EventHandler<ActionEvent>() {
              @Override public void handle(ActionEvent actionEvent) {
                Calendar time = Calendar.getInstance();
                String hourString = StringUtilities.pad(2, ' ', time.get(Calendar.HOUR) == 0 ? "12" : time.get(Calendar.HOUR) + "");
                String minuteString = StringUtilities.pad(2, '0', time.get(Calendar.MINUTE) + "");
                String secondString = StringUtilities.pad(2, '0', time.get(Calendar.SECOND) + "");
                String ampmString = time.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";
                setText(hourString + ":" + minuteString + ":" + secondString + " " + ampmString);
              }
            }
          ),
          new KeyFrame(Duration.seconds(1))
        );
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
      }
    }
    
    class StringUtilities {
      /**
       * Creates a string left padded to the specified width with the supplied padding character.
       * @param fieldWidth the length of the resultant padded string.
       * @param padChar a character to use for padding the string.
       * @param s the string to be padded.
       * @return the padded string.
       */
      public static String pad(int fieldWidth, char padChar, String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = s.length(); i < fieldWidth; i++) {
          sb.append(padChar);
        }
        sb.append(s);
    
        return sb.toString();
      }
    }
    

    Digital clock sample output:

    Digital clock output

    0 讨论(0)
  • 2020-11-30 05:29

    Excellent responses, thank you jewelsea for your input it helped me a lot.

    I updated the DigitalClock posted previously in a leaner format using Java 8. Using the additions of Java 8 like Date API and of course the lambdas.

     import javafx.animation.Animation;
     import javafx.animation.KeyFrame;
     import javafx.animation.Timeline;
     import javafx.scene.control.Label;
     import javafx.util.Duration;
    
     import java.time.LocalTime;
     import java.time.format.DateTimeFormatter;
    
     public class DigitalClock extends Label
     {
        private static DateTimeFormatter SHORT_TIME_FORMATTER =       DateTimeFormatter.ofPattern("HH:mm:ss");
    
        public DigitalClock()
        {
            bindToTime();
        }
    
        private void bindToTime() {
            Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0),
                                                          event -> setText(LocalTime.now().format(SHORT_TIME_FORMATTER))),
                                             new KeyFrame(Duration.seconds(1)));
    
            timeline.setCycleCount(Animation.INDEFINITE);
            timeline.play();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 05:31

    There are numerous ways to achieve that, the most convenient would be to use JavaFX's DataBinding mechanism:

    // assuming you have defined a StringProperty called "valueProperty"
    Label myLabel = new Label("Start");
    myLabel.textProperty().bind(valueProperty);
    

    This way, every time your valueProperty gets changed by calling it's set method, the label's text is updated.

    0 讨论(0)
  • 2020-11-30 05:40

    How about using SimpleDateFormat? There's no need for the StringUtilities class!

    private void bindToTime() {
      Timeline timeline = new Timeline(
        new KeyFrame(Duration.seconds(0),
          new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              Calendar time = Calendar.getInstance();
              SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
              setText(simpleDateFormat.format(time.getTime()));
            }
          }
        ),
        new KeyFrame(Duration.seconds(1))
      );
      timeline.setCycleCount(Animation.INDEFINITE);
      timeline.play();
     }
    }
    
    0 讨论(0)
提交回复
热议问题