1

I am developing my first application, and I use javafx for my GUI part. In this code, while pressing the button, I am trying to connect to mail server:

public class SettingWindowController implements Initializable {
    @FXML
    TextField hostTextField;
    @FXML
    TextField loginTextField;
    @FXML
    TextField passwordTextField;
    @FXML
    TextField portTextField;
    @FXML
    Label statusConnectionOK;
    @FXML
    ChoiceBox choiceStore;

    public void pressConnect(ActionEvent actionEvent) throws InterruptedException {
        Task task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                saveProperty();
                CheckMailConnect connect = new CheckMailConnect();
                if (connect.checkConnect()) {
                    statusConnectionOK.setText("");
                    statusConnectionOK.setStyle("-fx-text-fill:green;");
                    statusConnectionOK.setText("Connection OK");
                } else {
                    statusConnectionOK.setText("");
                    statusConnectionOK.setStyle("-fx-text-fill:red;");
                    statusConnectionOK.setText("Connection failed");
                }
                return null;
            }
        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
    }
}

But I have this problem:

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:438) 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$61(BehaviorSkinBase.java:197) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$$Lambda$122/82162992.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:144) 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:145) at com.helpdesk.gui.controller.SettingWindowController$1.call(SettingWindowController.java:41) at com.helpdesk.gui.controller.SettingWindowController$1.call(SettingWindowController.java:33) at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.lang.Thread.run(Thread.java:745)

Tell me please, how can I fix this error?

Thanks, experts.

But I am not sure know how to this make in my app. This my controller from which I open new window:

public class Controller implements Initializable {
    @FXML
    private MenuItem itemSetting;
    @FXML
    private Stage stage;
    @FXML
    private Parent root;

    @FXML
    public void pressSettingItem(ActionEvent actionEvent) throws IOException {
        if (actionEvent.getSource() == itemSetting) {
            stage = new Stage();
            FXMLLoader loader = new FXMLLoader();

            loader.setLocation(Controller.class
                                         .getResource("/SettingsWindows.fxml"));

            root =  loader.load();
            stage.setScene(new Scene(root, 300,300));
            stage.setTitle("Setting mode");
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.showAndWait();
        }
    }

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

Maybe I was wrong to write this application :)

Turing85
  • 18,217
  • 7
  • 33
  • 58
Anton Konikov
  • 49
  • 1
  • 1
  • 7

2 Answers2

2

You are not updating the GUI from the FX GUI thread, which isn't allowed. You'll need to use the following:

Platform.runLater(new Runnable() {
      @Override
      public void run() {
         //Update your GUI here
      }
  });

For further reading, take a look at Platform.runLater()

JackWhiteIII
  • 1,388
  • 2
  • 11
  • 25
1

The problem is that only a JavaFX thread is allowed to change GUI-elements. To redirect actions, that change the GUI, back to the FX User Thread, call Platform.runLater(Runnable r). You may also want look at this question.

There is another way to make a thread to an FX User Thread, but this seems to be a bug within JavaFX and thus may be patched out in the future.

Community
  • 1
  • 1
Turing85
  • 18,217
  • 7
  • 33
  • 58