API调用似乎阻止了JavaFX代码

API调用似乎阻止了JavaFX代码,java,events,javafx,Java,Events,Javafx,嘿,当我从JavaFX视图提交时,我遇到了一个问题。在提交时,我希望实现以下链: 将光标更改为等待符号 设置标签文本“正在加载…” 进行API调用 将标签文本设置为“已完成,请点击刷新” 将光标设置回默认值 我想这样做,因为API调用确实锁定了(web)视图的其余部分,我不希望用户四处点击导致程序崩溃。我编写这段代码是为了实现上述事件链 Button submit = new Button(); submit.setPadding(new Insets(5)); submit.setText("

嘿,当我从JavaFX视图提交时,我遇到了一个问题。在提交时,我希望实现以下链:

  • 将光标更改为等待符号
  • 设置标签文本“正在加载…”
  • 进行API调用
  • 将标签文本设置为“已完成,请点击刷新”
  • 将光标设置回默认值
  • 我想这样做,因为API调用确实锁定了(web)视图的其余部分,我不希望用户四处点击导致程序崩溃。我编写这段代码是为了实现上述事件链

    Button submit = new Button();
    submit.setPadding(new Insets(5));
    submit.setText("Submit");
    submit.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            try {
                scene.setCursor(Cursor.WAIT);
                label.setText("loading...");
                System.out.println("loading");
                model.newRootNode(searchIndividual.getText(), Integer.valueOf(numberField.getText()));
                // This makes the API call
                System.out.println("finished");
                label.setText("Done! Please hit \'Refresh\'");
                scene.setCursor(Cursor.DEFAULT);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    vbox.getChildren().add(submit);
    
    按钮提交=新建按钮();
    提交。设置填充(新插图(5));
    submit.setText(“提交”);
    submit.setOnAction(新的EventHandler(){
    @凌驾
    公共无效句柄(ActionEvent事件){
    试一试{
    scene.setCursor(Cursor.WAIT);
    label.setText(“加载…”);
    系统输出打印项次(“加载”);
    model.newRootNode(searchIndividual.getText(),Integer.valueOf(numberField.getText());
    //这使得API调用
    系统输出打印项次(“完成”);
    label.setText(“完成!请点击‘刷新’”);
    scene.setCursor(Cursor.DEFAULT);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    });
    vbox.getChildren().add(submit);
    

    使用eclipse调试器,我无法使标签文本更改可见,但光标似乎可以工作。除此之外,我还使用了
    sysouts()
    来检查API调用前后的代码是否得到了executet,它是否打印
    加载
    完成
    。标签设置为
    Done!请点击“刷新”
    ,它会将光标设置为
    光标。如果我以后不重写它,请稍候。
    为什么API调用之前的代码似乎没有执行?或者说提供视觉反馈?

    从ui线程调用事件处理程序,在您更改ui内容后,该线程无法自由刷新场景。在不同的线程上执行长时间运行的操作,并让ui线程继续执行修复此问题的任务。您可以简单地使用
    Platform.runLater
    从启动或使用的非ui线程对ui进行更改,该线程旨在执行以下工作:

    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            // makes the long-running API call
            return null;
        }
    };
    task.setOnRunning((WorkerStateEvent event) -> {
        // disable ui
    });
    
    task.setOnCancelled((WorkerStateEvent event) -> {
        // reenable ui
        // handle cancel
    });
    task.setOnSucceeded((WorkerStateEvent event) -> {
        // reenable ui
        // handle succeed
    });
    
    task.setOnFailed((WorkerStateEvent event) -> {
        // reenable ui
        // handle failed task e.g.:
        System.err.println("Oops, Error:");
        task.getException().printStackTrace(System.err);
    });
    
    Thread t = new Thread(task);
    // thread shouldn't prevent program shutdown
    t.setDaemon(true);
    t.start();
    
    Task Task=新任务(){
    @凌驾
    受保护的Void调用()引发异常{
    //进行长时间运行的API调用
    返回null;
    }
    };
    task.setOnRunning((WorkerStateEvent事件)->{
    //禁用用户界面
    });
    task.setOnCancelled((WorkerStateEvent事件)->{
    //可重入用户界面
    //处理取消
    });
    task.setOnSucceeded((WorkerStateEvent事件)->{
    //可重入用户界面
    //处理成功
    });
    task.setOnFailed((WorkerStateEvent事件)->{
    //可重入用户界面
    //处理失败的任务,例如:
    System.err.println(“Oops,Error:”);
    task.getException().printStackTrace(System.err);
    });
    线程t=新线程(任务);
    //线程不应阻止程序关闭
    t、 setDaemon(true);
    t、 start();
    

    还要注意,如果抛出异常,处理异常的方式将不会再次解锁ui,因为该部分代码位于异常发生的块内。

    是否确定在API调用之前对游标和文本更新的调用不可见,或者如果它们发生得太快,以至于你只能在API调用后看到更新?好吧,如果我单击按钮,其他一切都会冻结。大约13秒后显示
    Done!请点击“刷新”
    ,但中间没有任何内容,没有不同的光标,没有标签显示加载…