JavaFX FX应用程序线程问题

时间:2018-11-29 08:53:26

标签: multithreading javafx task

我正在做一个桌面应用程序,并且我正在后台执行繁重的任务。我希望更新进度条。我的程序正常运行,我可以看到进度条不是我的问题。我的问题是我使用在2个线程中运行的2个任务,以便同时更新进度条和繁重的任务。我的问题是:是否有更好的方法可以避免错误“线程“ Thread-5”中的异常” java.lang.IllegalStateException:不在FX应用程序线程上; currentThread = Thread-5”。

当然,我已经在Internet上进行了检查,并且我总是发现:最好使用Platform.runLater。好的,但是在两个新线程中,我都需要类的属性,例如,当我使用Platform.runLater((new Runnable()...))时,无法访问例如“ this.myAttribute”。是RunLater解决方案,我看不到吗?

这是一堆代码,在JavaFX线程中调用了setConnection方法,另外我创建了2个。一个用于进度条,另一个用于我的任务:

@FXML
    private void setConnection() {
        try {
            this.onOffButton.setSelected(false);
            if (!this.hubModel.isConnected()) {
                this.progressBar.progressProperty().unbind();
                @SuppressWarnings("unchecked")
                OperationTask progressBarOperationTask = new OperationTask(this) {
                    @Override
                    public Void call() {
                        HubController hubController = (HubController) this.getHubController();
                        hubController.getProgressBar().setVisible(true);
                        for (int i = 0; i < 100; i++) {
                            try {
                                Thread.sleep(25);
                            } catch (InterruptedException e) {
                                Thread.interrupted();
                                break;
                            }
                            updateProgress(i + 1, 100);
                        }
                        hubController.getProgressBar().setVisible(false);
                        return null;
                    }
                };
                this.progressBar.progressProperty().bind(progressBarOperationTask.progressProperty());
                Thread timeThread = new Thread(progressBarOperationTask);
                timeThread.setDaemon(true);
                timeThread.start();
            }

            @SuppressWarnings("unchecked")
            OperationTask connectionOperationTask = new OperationTask(this) {

                @Override
                protected Object call() throws Exception {
                    HubController hubController = (HubController) this.getHubController();
                    if (hubController.getUserID().getText().equals("") || hubController.getUserPW().getText().equals("")) {
                        hubController.getCommentBottom().setText("Please enter a user name and a password.");
                        hubController.getOnOffButton().setSelected(false);
                    } else {
                        hubController.getHubModel().setIdUser(hubController.getUserID().getText());
                        hubController.getHubModel().setPwUser(hubController.getUserPW().getText());
                        String comment = hubController.getHubModel().setConnection();
                        if (!comment.equals("Connection established.")) {
                            hubController.getOnOffButton().setSelected(false);
                        }
                        if (hubController.getHubModel().isConnected()) {
                            hubController.getConnectionStatus().setText("Connected");
                            hubController.getConnectionStatus().setStyle("-fx-font-weight: bold");
                            String commentProject = hubController.getHubModel().getAllProjects();
                            if (commentProject.equals("")) {
                                TextFields.bindAutoCompletion(hubController.getCloneAndMoveController().getNewProjectNameTextField(), hubController.getHubModel().getProjectsList());
                            } else {
                                comment = commentProject;
                            }
                            hubController.getOnOffButton().setSelected(true);
                        } else {
                            hubController.getConnectionStatus().setText("Not connected");
                            hubController.getConnectionStatus().setStyle("-fx-font-weight: regular");
                        }
                        hubController.getCommentBottom().setText(comment);
                    }
                    return null;
                }

            };
            Thread connectionThread = new Thread(connectionOperationTask);
            connectionThread.setDaemon(true);
            connectionThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

此外,如果您发现有待改进的地方,我将不胜感激(我是Java新手)

谢谢。

1 个答案:

答案 0 :(得分:1)

您可以从Platform.runLater()访问对象。您为其创建的新Runnable可以访问对象的this实例。参见示例:

private String myAttribute = "hello";

@Override
public void randomMethod() {
    //...

    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            System.out.println(myAttribute);
        }
    });
}