it-swarm.com.ru

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

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

Ошибка также неоднозначна Not On fx application thread and current thread- javafxapplication 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);
}
34
Rajesh

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

15
Rajesh

Призвание

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

это тоже исправлю.

48
Martin Pfeffer

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

 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;
     }
 };
37
vinay

Это должно произойти, когда вы пытаетесь изменить какой-либо компонент компонента, например текст метки. Бег так работает всегда:

@FXML Label myLabel;

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

Вы можете изменить форму или перейти к другому представлению или 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();

        }

    }

}
5
diego matos - keke

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

2
WillBD