on UI - primaryStage.scene.cursor = Cursor.WAIT try { do stuff off UI... } finally { on UI - primaryStage.scene.cursor = Cursor.DEFAULT }在运行过程中,我可以启动另一个进程,它可以快速完成,并在第一个任务完成之前恢复游标。
我不介意在第一个任务完成时“等待”,但我不认为这意味着在UI线程上执行工作?javafx中提供的这种模式有内置的解决方案吗?
视图
label 'From'
comboBox(items: bind(model.wcomboFromItemsProperty()), value: bind(model.wcomboFromProperty()), selectFromAction)
label 'To'
comboBox(items: bind(model.wcomboFromItemsProperty()), value: bind(model.wcomboToProperty()), selectToAction)模型
@FXObservable ListElement wcomboFrom = new ListElement()
@FXObservable ListElement wcomboTo = new ListElement()
@FXObservable List wcomboFromItems = FXCollections.observableArrayList()
@FXObservable List wcomboToItems = FXCollections.observableArrayList()
final ObjectProperty<Cursor> CURSOR_DEFAULT = new SimpleObjectProperty<>(Cursor.DEFAULT)
final ObjectProperty<Cursor> CURSOR_WAIT = new SimpleObjectProperty<>(Cursor.WAIT)控制器
//lifecycle
void onReadyStart(GriffonApplication application) {
loadWindowData()
}
// both combo boxes contain the same items
protected void loadWindowData() {
def list = [new ListElement(textValue: '')]
list.addAll dataService.getData().collect {
new ListElement(textValue: it.name, objectValue: it)
}
runInsideUIAsync {
model.wcomboFromItems.addAll(list)
model.wcomboToItems.addAll(list)
}
}
void selectFrom() {
performAction {
gcListFrom = getControlList(model.wcomboFrom.objectValue)
setTreeItems(model.wtreeGcFrom, gcListFrom, model.wcomboFrom)
setTreeItems(model.wtreeGcTo, gcListTo, model.wcomboTo)
}
}
void selectTo() {
performAction {
gcListTo = getControlList(model.wcomboTo.objectValue)
setTreeItems(model.wtreeGcTo, gcListTo, model.wcomboTo)
}
}
def performAction = {c ->
Task<Void> t = new Task() {
@Override protected Void call() {
println "Running closure " + isUIThread()
c.call()
}
}
runInsideUISync {
application.primaryStage.scene.cursorProperty().bind(Bindings.when(t.runningProperty())
.then(model.CURSOR_WAIT).otherwise(model.CURSOR_DEFAULT))
}
runOutsideUI(t)
}其他
@EqualsAndHashCode(includes = 'textValue')
class ListElement implements Serializable {
String textValue = ""
Serializable objectValue // Serializable object from business model
@Override
String toString() {
textValue
}
}格里芬框架会自动调用UI线程之外的onAction控制器事件。GroovyFX包含一些魔术,它添加了一个绑定到selectionModel.selectedItemProperty的"onSelect“动作:
class GroovyFXEnhancer {
static void enhanceClasses() {
...
ComboBox.metaClass {
cellFactory << { Closure closure -> delegate.setCellFactory(closure as Callback)}
onSelect << { Closure closure ->
delegate.selectionModel.selectedItemProperty().addListener(closure as ChangeListener);
}
...
}
}发布于 2015-06-03 11:52:15
javafx中提供的这种模式有内置的解决方案吗?
我建议您使用内置的任务 ;)
它有预定义的方法来处理所需的一切。
private Task<Void> backgroundTask = new Task() {
@Override
protected Void call() throws Exception {
// Something to do on background thread ;
return null;
}
};它有一个runningProperty(),可以绑定到场景的cursorProperty()。
您可以创建两个包含ObjectProperty<Cursor>和Cursor.DEFAULT的CURSOR.WAIT。
final ObjectProperty<Cursor> CURSOR_DEFAULT = new SimpleObjectProperty<>(Cursor.DEFAULT);
final ObjectProperty<Cursor> CURSOR_WAIT = new SimpleObjectProperty<>(Cursor.WAIT);然后,您可以将它们绑定到任务:
scene.cursorProperty().bind(Bindings.when(backgroundTask.runningProperty())
.then(CURSOR_WAIT).otherwise(CURSOR_DEFAULT));这是一个单独的问题,还是某种程度上是相关的?
如果您在ComboBox上的操作是以某种方式调用后台线程,那么它可能是相关的,否则很难进行注释。
https://stackoverflow.com/questions/30616552
复制相似问题