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