本文介绍了新线程,阶段关闭后应用程序仍在运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我遵循了本教程: https://www.youtube.com/watch?v= gyyj57O0FVI

So I followed this tutorial: https://www.youtube.com/watch?v=gyyj57O0FVI

,我在javafx8中编写了完全相同的代码.

and I made exactly the same code in javafx8.

public class CountdownController implements Initializable{

@FXML
private Label labTime;

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

    new Thread(){
        public void run(){
            while(true){
                Calendar calendar = new GregorianCalendar();
                int hour = calendar.get(Calendar.HOUR);
                int minute = calendar.get(Calendar.MINUTE);
                int second = calendar.get(Calendar.SECOND);
                String time = hour + ":" + minute + ":" + second;

                labTime.setText(time);
            }

        }
    }.start();
}

关闭窗口后,应用程序/线程仍在系统中运行.我的猜测是因为无限循环,但是线程不应该在应用程序关闭时终止吗?

After I close the Window, application/thread is still running in the system. My guess its because the infinite loop, but shouldnt the thread be terminated with application closing?

第二件事是,当我尝试为Label设置文本时,出现错误:

Second thing is that when I try to set the text for Label I get the error:

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
    at javafx.scene.Parent$2.onProposedChange(Parent.java:364)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
    at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$60(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$$Lambda$144/1099655841.call(Unknown Source)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
    at javafx.scene.control.Labeled.setText(Labeled.java:146)
    at application.CountdownController$1.run(CountdownController.java:29)

...是的,我将阅读有关线程的更多信息,但我想知道这些问题的答案.

...yes, I am going to read more about threads, but I would like to know the answer to these questions.

推荐答案

第一部分

一个线程在创建时独立于其他线程运行.您有一个具有无限循环的新线程,这意味着即使关闭阶段,该线程也将永远运行.

Part I

A thread, when created, runs independent of other threads. You have a new thread which has an infinite loop, which implies, it will keep running forever, even after the stage has been closed.

通常不建议使用无限循环,因为要打破该循环非常困难.

Normally, using a infinite loop is not advised, because breaking out of it is very difficult.

建议您使用:

  • TimerTask
  • ScheduledExecutorService

然后您可以呼叫其中一个(根据您使用的是什么)

You can then call either one of them (based on whatever you are using)

  • TimerTask.cancel()
  • ScheduledExecutorService.shutdownNow()

舞台关闭时.您可以使用类似:

when your stage is closed. You can use something like :

stage.setOnCloseRequest(closeEvent -> {
       timertask.cancel();
});

JavaFX API的 (感谢James_D评论的)

这些不需要显式取消,因为ScheduledService使用守护程序线程,而AnimationTimer在JavaFX线程上运行.

These do not need to be explicitly canceled as ScheduledService uses daemon threads and AnimationTimer runs on the JavaFX thread.

  • ScheduledService
  • AnimationTimer

问题的第二部分已在论坛中一次又一次地得到回答.

Your second part of the question has been answered time and again in the forum.

由于创建了新线程并尝试更新label(它是一个JavaFX节点),因此它将引发异常.有关更多信息,请访问:

Since you have created a new thread and trying to update label, which is a JavaFX node, it throws the exception. For more information, please visit:

尝试删除形状时出现JavaFX错误

为什么会收到java.lang.IllegalStateException不在FX应用程序线程上"在JavaFX上?

Javafx在使用计时器时不在fx应用程序线程上

这篇关于新线程,阶段关闭后应用程序仍在运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 18:48