Multithreading JavaFX应用程序线程问题

Multithreading JavaFX应用程序线程问题,multithreading,javafx,task,Multithreading,Javafx,Task,我正在做一个桌面应用程序,我正在后台执行一项繁重的任务。我想更新进度条。我的程序运行正常,我可以看到这里的进度条不是我的问题。我的问题是,我使用2个线程中运行的2个任务来更新进度条和繁重的任务。我的问题是:是否有更好的方法来避免错误“线程中的异常”thread-5“java.lang.IllegalStateException:不在FX应用程序线程上;currentThread=thread-5” 当然,我已经在网上查过了,我总是发现:更好地使用Platform.runLater。好的,但在这两

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

当然,我已经在网上查过了,我总是发现:更好地使用Platform.runLater。好的,但在这两个新线程中,我都需要类的属性,例如,当我使用Platform.runLater((new Runnable()…)时,我无法访问例如“this.myAttribute”。RunLater是解决方案,但我看不到

下面是一组代码,方法setConnection在JavaFXThread中调用,我创建了另外两个。一个用于progressbar,另一个用于我的任务:

@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();
        }
    }
@FXML
私有void setConnection(){
试一试{
此.onOffButton.setSelected(假);
如果(!this.hubModel.isConnected()){
this.progressBar.progressProperty().unbind();
@抑制警告(“未选中”)
OperationTask progressBarOperationTask=新的OperationTask(此){
@凌驾
公开作废通知(){
HubController=(HubController)this.getHubController();
hubController.getProgressBar().setVisible(true);
对于(int i=0;i<100;i++){
试一试{
睡眠(25);
}捕捉(中断异常e){
Thread.interrupted();
打破
}
updateProgress(i+1100);
}
hubController.getProgressBar().setVisible(false);
返回null;
}
};
this.progressBar.progressProperty().bind(progressBarOperationTask.progressProperty());
线程时间线程=新线程(progressBarOperationTask);
timeThread.setDaemon(true);
timeThread.start();
}
@抑制警告(“未选中”)
OperationTask connectionOperationTask=新建OperationTask(此){
@凌驾
受保护对象调用()引发异常{
HubController=(HubController)this.getHubController();
if(hubController.getUserID().getText().equals(“”)| | hubController.getUserPW().getText().equals(“”){
hubController.getCommentBottom().setText(“请输入用户名和密码”);
hubController.getOnOffButton().setSelected(false);
}否则{
hubController.getHubModel().setIdUser(hubController.getUserID().getText());
hubController.getHubModel().setPwUser(hubController.getUserPW().getText());
String comment=hubController.getHubModel().setConnection();
如果(!comment.equals(“已建立连接”)){
hubController.getOnOffButton().setSelected(false);
}
if(hubController.getHubModel().isConnected()){
hubController.getConnectionStatus().setText(“已连接”);
hubController.getConnectionStatus().setStyle(“-fx font-weight:bold”);
字符串commentProject=hubController.getHubModel().getAllProjects();
if(注释项目等于(“”){
TextFields.bindAutoCompletion(hubController.getCloneAndMoveController().getNewProjectNameTextField(),hubController.getHubModel().getProjectsList());
}否则{
评论=评论项目;
}
hubController.getOnOffButton().setSelected(true);
}否则{
hubController.getConnectionStatus().setText(“未连接”);
hubController.getConnectionStatus().setStyle(“-fx font-weight:regular”);
}
hubController.getCommentBottom().setText(注释);
}
返回null;
}
};
线程连接线程=新线程(connectionOperationTask);
ConnectionRead.setDaemon(true);
connectionThread.start();
}捕获(例外e){
e、 printStackTrace();
}
}
此外,如果您看到一些可以改进的地方,我将不胜感激(我是java新手)


谢谢。

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

private String myAttribute = "hello";

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

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

如果没有示例代码,很难理解和回答。请提供一份报告。简而言之,除了
平台,没有真正的替代品;较长的版本是-您应该只在实际修改UI的最小代码段上使用
runLater
。我不同意@Itai的替代方案,但强烈同意您必须提供MCVE才能获得任何帮助。@PrzemekKrysztofiak-其他选项是什么?对JavaFX中UI的任何更改都必须在FX线程上完成-无论您如何做,它在功能上肯定与使用
平台几乎相同。。。还是我遗漏了什么?有没有可能有你的密码(