«Не в приложении FX» Правила исключений - PullRequest
0 голосов
/ 25 октября 2018

Всем известно, что только поток JavaFX должен позволять изменять GUI в приложениях JavaFX, но я часто получаю странное поведение в связи с нарушениями этого правила, поэтому я написал эту простую программу:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{

        VBox root = new VBox();
        CheckBox checkBox = new CheckBox("");
        checkBox.setSelected(false);
        root.getChildren().add(checkBox);
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
        new Thread(()->{
                System.out.println("is FX:"+Platform.isFxApplicationThread());
                try {
                    //line under is 28
                    checkBox.selectedProperty().setValue(!checkBox.isSelected());
                    System.out.println("checkBox selectedProperty is change to:"+checkBox.isSelected()+","+ checkBox.selectedProperty().get());
                }catch (Exception e){
                    System.out.println("checkBox change of selectedProperty is not allow from not FX thread");
                }
                try {
                    //line under is 35
                    checkBox.textProperty().set("test");
                    System.out.println("checkBox textProperty change to: "+checkBox.getText()+","+ checkBox.textProperty().get());
                }catch (Exception e){
                    System.out.println("checkBox change of textProperty is not allow from not FX thread");
                }
            System.out.println("end of thread");
        }).start();

    }


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

Вывод:

is FX:false
checkBox selectedProperty is change to:true,true
checkBox textProperty change to: test,test
end of thread
Exception in thread "Thread-3" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
    at javafx.graphics/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:247)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
    at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:493)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:271)
    at javafx.controls/javafx.scene.control.skin.CheckBoxSkin.updateChildren(CheckBoxSkin.java:106)
    at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.lambda$new$11(LabeledSkinBase.java:219)
    at javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:49)
    at javafx.base/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
    at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
    at javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
    at javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
    at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
    at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
    at sample.Main.lambda$start$0(Main.java:35)
    at java.base/java.lang.Thread.run(Thread.java:844)

, как вы можете видеть, на GUI влияют 2 изменения:

enter image description here

но Исключение это только в строке 35 (textProperty изменение), а не в строке 28 (selectedProperty изменение)

, поэтому мой вопрос, это ошибка или это поведение имеет разумное объяснение, и если естьтакое, что это такое?

Не знаю, имеет ли это значение, но я работаю с Java 9

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Когда вы меняете сцену из другого потока, происходит одно из следующих действий:

  • Если вам повезет, вы получите исключение
  • В противном случае могут возникнуть странные условия гонки..

Не разрешается создавать узел и изменять его извне потока приложения FX, если узел не присоединен к сцене.

При установкеэтот узел графа сцены, то вы должны использовать поток приложения FX.

0 голосов
/ 25 октября 2018

Это нормальное поведение.Вы редактируете графический интерфейс из потока без графического интерфейса, переводя графический интерфейс в нестабильное состояние.Впоследствии происходит исключение, когда поток графического интерфейса пытается обновить графический интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...