web-dev-qa-db-fra.com

Heure et date de JavaFX Live

Je construis actuellement une application utilisant JavaFx avec une fonctionnalité supplémentaire qui affiche la date et l'heure actuelles dans le coin supérieur de la scène. Depuis que je suis nouveau sur JavaFX, je ne sais pas comment implémenter celui-ci.

J'ai essayé d'utiliser un ancien code dans swing mais j'ai eu une erreur IllegalStateException.

Voici mon code.

MainMenuController.Java

@FXML private Label time;

private int minute;
private int hour;
private int second;

@FXML
public void initialize() {

    Thread clock = new Thread() {
        public void run() {
            for (;;) {
                DateFormat dateFormat = new SimpleDateFormat("hh:mm a");
                Calendar cal = Calendar.getInstance();

                second = cal.get(Calendar.SECOND);
                minute = cal.get(Calendar.MINUTE);
                hour = cal.get(Calendar.HOUR);
                //System.out.println(hour + ":" + (minute) + ":" + second);
                time.setText(hour + ":" + (minute) + ":" + second);

                try {
                    sleep(1000);
                } catch (InterruptedException ex) {
                     //...
                }
            }
        }
    };
    clock.start();
}

MainMenu.fxml

 <children>
   <Label fx:id="time" textFill="WHITE">
     <font>
       <Font name="Segoe UI Black" size="27.0" />
     </font>
   </Label>
   <Label fx:id="date" textFill="WHITE">
     <font>
       <Font name="Segoe UI Semibold" size="19.0" />
     </font>
   </Label>
 </children>

Main.Java

public class Main extends Application {

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

   @Override
   public void start(Stage primaryStage) throws Exception {
       Parent root = FXMLLoader.load(getClass().getResource("view/MainMenu.fxml"));
       primaryStage.setScene(new Scene(root,1366, 768));
       primaryStage.show();
   }
}

Comme vous le constatez, je l'ai testé en imprimant le temps réel dans la console. Oui, cela a fonctionné, mais l'étiquette est toujours statique.

7
Bryan Reyes

Je pense que vous avez besoin de FX UI Thread Platform.runLater(...) pour cela, mais vous pouvez faire quelque chose comme ça en utilisant Timeline dans votre classe de contrôleur,

@FXML
public void initialize() {

    Timeline clock = new Timeline(new KeyFrame(Duration.ZERO, e -> {        
        LocalTime currentTime = LocalTime.now();
        time.setText(currentTime.getHour() + ":" + currentTime.getMinute() + ":" + currentTime.getSecond());
    }),
         new KeyFrame(Duration.seconds(1))
    );
    clock.setCycleCount(Animation.INDEFINITE);
    clock.play();
}
12
Shekhar Rai

La réponse @Shekhar Rai fonctionne bien, mais voici une version plus courte qui fonctionne assez bien aussi.

@FXML
Label dateTime;

@Override
public void initialize(URL location, ResourceBundle resources) {
    initClock();
}

private void initClock() {

    Timeline clock = new Timeline(new KeyFrame(Duration.ZERO, e -> {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        dateTime.setText(LocalDateTime.now().format(formatter));
    }), new KeyFrame(Duration.seconds(1)));
    clock.setCycleCount(Animation.INDEFINITE);
    clock.play();
}

Le principal avantage est que vous n'avez pas à définir toutes les variables (secondes, minutes, ...)

9
WEGSY85