Как избежать не в потоке приложения FX; currentThread = Ошибка потока приложения JavaFX?

ниже фрагментов кода дает мне ошибку Not on FX application thread; currentThread=JavaFX Application Thread.Это приложение отлично работало в java 1.7, но когда я переместил его в fx8, он теперь дает ошибку. когда я запускаю приложение с моей 1-й попытки, оно работает по назначению .Но после закрытия сцены и открытия ее снова она не работает.

ошибка также неоднозначна Not On fx application thread and current thread- javafx application thread.Что это означало, не в потоке приложения fx, если текущий поток является потоком приложения fx.

      progressDialog = createProgressDialog(service);
        progressDialog.show();
        progressDialog.setOnCloseRequest(new EventHandler<WindowEvent>() {
          @Override
          public void handle(WindowEvent event) {
            // if (service.isRunning()) {
            // service.cancel();
            progressDialog.close();
            // }
          }
        });

      }

      @SuppressWarnings("unchecked")
      private Stage createProgressDialog(final Service<IStatus> service) {
        stage = new Stage();

        URL url = FileLocator.find(Activator.getDefault().getBundle(),
            new Path("icons/xxx_16x16.png"), null); //$NON-NLS-1$
        stage.getIcons().add(new Image(url.getFile()));
        stage.setTitle("Downloading ..."); //$NON-NLS-1$
        // Creating StackPane
        stage.initModality(Modality.WINDOW_MODAL);
}

6 ответов


Это произошло со мной, когда я изменял элемент UI из задачи в javafx 2, как элементы listview.Задача, Которая Изменяет График Сцены помог мне решить проблему, т. е. обновить элементы пользовательского интерфейса по

 final ListView<String> group = new ListView ();

 Task<Void> task = new Task<Void>() {

     @Override protected Void call() throws Exception {

         group.getItems().clear();  

          for (int i=0; i<100; i++) {                
             Platform.runLater(new Runnable() {
                 @Override public void run() {
                     group.getItems.add(i);
                 }
             });
         }
         return null;
     }
 };

вызов

Platform.runLater(new Runnable(){
// ...
});

исправить, тоже.


Platform.setImplicitExit(false); решить мою проблему. Я думаю, что они изменили реализацию в JavaFX 8, поэтому тот же код, который работает без каких-либо проблем в JavaFX 2, дает не поток приложений fx есть ошибки.


это должно произойти, когда вы пытаетесь изменить некоторый компонент UI, например текст метки. Запуск, как это работает всегда:

@FXML Label myLabel;

Platform.runLater(new Runnable(){
   myLabel.setText("some text");
});

Вы можете изменить форму или перейти к другому представлению или fxml с этим в любой части вашего кода:

Platform.runLater(() -> {
                            try {
                                Stage st = new Stage();
                                Parent sceneMain = FXMLLoader.load(getClass().getResource("/com/load/free/form/LoadFile.fxml"));
                                Scene scene = new Scene(sceneMain);
                                st.setScene(scene);
                                st.setMaximized(true);
                                st.setTitle("load");
                                st.show();
                            } catch (IOException ex) {
                                Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        });

мой пример в моем контроллере:

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;


public class LoginController implements Initializable {

    @FXML
    private TextField txtUser;

    @FXML
    private TextField txtPassword;

    @FXML
    private Hyperlink urlForgetPassword;

    @FXML
    private Label lblError;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }

    public void isLoginAction(ActionEvent event) {
        String message = "Ingrese ";
        boolean isEmtpy = false;

        if (txtUser.getText().trim().isEmpty()) {
            message += "usuario y ";
            isEmtpy = true;
        }

        if (txtPassword.getText().trim().isEmpty()) {
            message += "contraseña  ";
            isEmtpy = true;
        }
        isEmtpy = false;
        if (isEmtpy) {
            message = message.substring(0, message.length() - 2);
            lblError.getStyleClass().remove("message_process");
            lblError.getStyleClass().add("message_error");
            lblError.setText(message);
        } else {
            lblError.getStyleClass().add("message_process");
            lblError.getStyleClass().remove("message_error");
            Task task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    updateMessage("Procesando...");
                    System.out.println("Asignando DATOS DE PRUEBA ");
                    String passEnc = Encripta.encriptar(txtPassword.getText(), Encripta.HASH_SHA1);
                    int typeRest = new RestConnection().getConnectionUser(txtUser.getText(), passEnc);
                    if (typeRest == 1) {
                        //Load Another form
                        Platform.runLater(() -> {
                            try {
                                Stage st = new Stage();
                                Parent sceneMain = FXMLLoader.load(getClass().getResource("/com/load/free/form/LoadFile.fxml"));
                                Scene scene = new Scene(sceneMain);
                                st.setScene(scene);
                                st.setMaximized(true);
                                st.setTitle("");
                                st.show();
                            } catch (IOException ex) {
                                Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        });

                    } else {
                        lblError.getStyleClass().remove("message_process");
                        lblError.getStyleClass().add("message_error");
                        updateMessage("Usuario y/o contraseña incorrectos");
                    }
                    return null;
                }
            };

            lblError.textProperty().bind(task.messageProperty());
            new Thread(task).start();

        }

    }

}

Это не показано явно в коде выше, но я уверен, что происходит то, что где-то вы создаете поток вне потока приложения (main) javafx, а затем пытаетесь выполнить операции над объектами javafx (например, закрытие, открытие окон и т. д.) на второй нить. Это строго запрещено, так как только основной поток может напрямую управлять объектами javafx. Если это становится требованием вашей программы, вам нужно использовать второй поток для других такие вещи, как вычисления и т. д. Вы должны использовать некоторую форму передачи сообщений, чтобы другой поток знал, что вы хотите сделать любое действие javafx.