管理任务

时间:2015-06-03 09:48:40

标签: javafx javafx-8 griffon groovyfx

  1. 我在UI之外,希望在东西出现时显示等待光标 发生并使用这种基本模式:

    on UI - primaryStage.scene.cursor = Cursor.WAIT try { do stuff off UI... } finally { on UI - primaryStage.scene.cursor = Cursor.DEFAULT }

  2. 运行时,我可以启动另一个快速完成的进程,并在第一个任务完成之前恢复Cursor。

    我不介意等待"第一个任务完成,但我不认为这意味着在UI线程上完成工作? 在javafx中是否有针对此模式的内置解决方案?

    1. 我的标签包含2个组合框。当我按下第二个组合框下拉时,即使光标当前处于默认状态,有时也会在列表上显示WAIT光标。如果我在列表的外侧/后侧移动鼠标指针,则光标将正确显示为默认值。这是一个单独的问题还是以某种方式相关的?
    2. 查看

      label 'From'
      comboBox(items: bind(model.wcomboFromItemsProperty()), value: bind(model.wcomboFromProperty()), selectFromAction)
      label 'To'
      comboBox(items: bind(model.wcomboFromItemsProperty()), value: bind(model.wcomboToProperty()), selectToAction)
      

      MODEL

      @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)
      

      CONTROLLER

      //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)
      }
      

      OTHER

      @EqualsAndHashCode(includes = 'textValue')
      class ListElement implements Serializable {
          String textValue = ""
          Serializable objectValue // Serializable object from business model
      
          @Override
          String toString() {
              textValue
          }
      }
      

      Griffon框架自动调用UI线程外部的onAction控制器事件。 GroovyFX包含一些魔法,可以添加一个&#34; onSelect&#34;绑定到selectionModel.selectedItemProperty的行动,即。

      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);
              }
              ...
          }
      }
      

2 个答案:

答案 0 :(得分:3)

  

javafx中是否有针对此模式的内置解决方案?

我建议你使用内置的Task;)

它有预定义的方法来处理你需要的一切。

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的{​​{1}}。

CURSOR.WAIT

然后你可以将它们绑定到任务:

final ObjectProperty<Cursor> CURSOR_DEFAULT = new SimpleObjectProperty<>(Cursor.DEFAULT);
final ObjectProperty<Cursor> CURSOR_WAIT = new SimpleObjectProperty<>(Cursor.WAIT);
  

这是一个单独的问题还是以某种方式相关?

如果您对ComboBox的操作以某种方式调用后台线程,那么它可能是相关的,否则很难评论。

答案 1 :(得分:0)

您还可以使用griffon-tasks-plugin http://griffon-plugins.github.io/griffon-tasks-plugin/

此插件提供与UI工具包agnostik类似SwingWorker的API,用于在后台线程中执行任务。