Для выполнения кода, связанного с GUI, через фиксированные промежутки времени в JavaFX, лучше использовать специально предназначенный для этого JavaFX API. Например, здесь вы можете использовать Timeline
: см., Например, JavaFX periodi c фоновая задача . Вы можете легко позвонить Timeline.stop()
, когда вам понадобится остановить его.
Убить работающий поток немного более тонко. Вам нужен логический флаг в вашем ChildWindowClass
и метод для его установки. Затем вы можете запросить остановку потока с помощью вызова этого метода. Вы должны проявить осторожность, чтобы изменения, внесенные в флаг в одном потоке, были видны другому; в этом случае достаточно сделать флаг volatile
. Должно работать следующее:
public class ChildWindowClass {
private Text txt;
private int _index = 0;
private SimpleDateFormat dateFrmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
private volatile boolean stopRequested ;
public void requestStop() {
stopRequested = true ;
}
public VBox getChildContent() {
txt = new Text("Child Window Test " + _index);
Label refreshClock = new Label(dateFrmt.format(new Date()));
Thread timerThread = new Thread(() -> {
// update to stop thread when request is sent
while (! stopRequested) {
try { Thread.sleep(5000); }
catch (InterruptedException e) {e.printStackTrace();}
Platform.runLater(() -> {
refreshClock.setText(dateFrmt.format(new Date()));
try {
System.out.println(dateFrmt.format(new Date()) + " - " + (txt == null ? "" : " not") + " NULL");
if(txt != null)
txt.setText("Child Window Test " + _index);
_index++;
}
catch (Exception e) {e.printStackTrace();}
});
}
});
timerThread.start();
return new VBox(txt, refreshClock);
}
}
И теперь вы можете сделать следующее. Обратите внимание, что я изменил какой-то другой код здесь; showAndWait()
будет фактически ждать, пока диалоговое окно не закроется, поэтому код после этого может предполагать, что диалоговое окно закрыто.
btn.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
final Stage dialog = new Stage();
dialog.setTitle("Sensors Assignment");
dialog.initModality(Modality.WINDOW_MODAL);
dialog.initOwner(primaryStage);
dialog.setResizable(false);
ChildWindowClass dialogUI = new ChildWindowClass();
VBox dialogVbox = dialogUI.getChildContent();
//dialogVbox.getChildren().add(closeButton);
Scene dialogScene = new Scene(dialogVbox);
dialog.setScene(dialogScene);
dialog.setOnCloseRequest(e -> {
System.out.println("Stage is closing");
dialog.close();
});
dialog.showAndWait();
dialogUI.requestStop();
}
});
Это не прервет поток, поэтому он продолжит свое текущее состояние сна, но он гарантированно завершится в течение пяти секунд после закрытия диалога. Если вам нужно убить его как можно скорее, вы можете сохранить ссылку на него и вызвать Thread.interrupt()
, когда вызывается requestStop()
, но это несколько усложняется. Как я уже говорил в начале, лучше использовать Timeline
и полностью избегать потоков для такого рода функций.