如何在javafx中创建线程

时间:2015-07-04 09:40:15

标签: java javafx

我正在开发我的第一个应用程序,我使用javafx作为我的GUI部分。 在此代码中,按下按钮时,我正在尝试连接到邮件服务器:

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();
    }
}

但我有这个问题:

  

线程中的异常&#34;线程-4&#34; java.lang.IllegalStateException:不是   在FX应用程序线程; currentThread = Thread-4         at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)         at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:438)         在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)         在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   资源)         at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler $ 1.changed(MultiplePropertyChangeListenerHandler.java:55)         在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)         在javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)         在javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)         在javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)         在javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)         在javafx.beans.property.StringProperty.setValue(StringProperty.java:65)         在javafx.scene.control.Labeled.setText(Labeled.java:145)         在com.helpdesk.gui.controller.SettingWindowController $ 1.call(SettingWindowController.java:41)         在com.helpdesk.gui.controller.SettingWindowController $ 1.call(SettingWindowController.java:33)         在javafx.concurrent.Task $ TaskCallable.call(Task.java:1423)         at java.util.concurrent.FutureTask.run(FutureTask.java:266)         在java.lang.Thread.run(Thread.java:745)

请告诉我,我该如何解决此错误?

谢谢,专家。

但我不知道如何在我的应用中制作这个。这是我打开新窗口的控制器:

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) {}
}

写这个应用程序可能我错了:)

2 个答案:

答案 0 :(得分:1)

您没有从FX GUI线程更新GUI,这是不允许的。您需要使用以下内容:

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

如需进一步阅读,请查看Platform.runLater()

答案 1 :(得分:0)

问题在于only a JavaFX thread is allowed to change GUI-elements。要将更改GUI的操作重定向回FX用户线程,请致电Platform.runLater(Runnable r)。您可能还需要查看this question

还有另一种方法可以为FX用户线程创建一个线程,但这似乎是JavaFX中的一个错误,因此可能会在将来修补。