2016-01-27 84 views
0

你能告诉我,我应该在哪里声明我的节点的事件侦听器,这些节点是添加在我的控制器类的旁边?在哪里添加事件到节点?

最好的办法就是用这个例子来解释一下:

我有我的控制器:

public class FXMLDocumentController implements Initializable { 

    @FXML 
    private AnchorPane root; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     TestTask test = new TestTask(root); 
     Thread th = new Thread(test); 
     th.start(); 
    }  
} 

然后,我有任务,这是在initialize方法开始:

public class TestTask extends Task<Void>{ 

    private AnchorPane root; 

    public TestTask(AnchorPane root){ 
     this.root = root; 
    } 

    @Override 
    protected Void call() throws Exception { 
     Button btn = new Button("TestButton"); 
     Platform.runLater(() -> { root.getChildren().add(btn); }); 
     return null; 
    } 
} 

我在这里做什么?我有一个带有AnchorPane的FXML作为根元素。它有id根。所以现在我开始在其中添加一个Button到我的根节点的任务。现在我想注册一个动作事件到按钮。我现在的问题是,我可以/应该在哪里注册听众。通常我在控制器中注册它们,但在这里我不能这样做,因为Button只存在于Task类中。我可以在Task类中注册它,但我认为它不适合大型应用程序。另一种方法是返回节点,以便我可以在控制器类中访问它,但是在这里我必须检查它是否已经添加(为此,我必须调用task.get(),这会停止我的应用程序。你告诉我:注册节点的监听器的最好方法是什么?

+1

但是,为什么不直接在控制器中创建按钮?我不明白你为什么需要这个线程? – Inge

+0

“我必须检查它是否已经添加”。由于您在'call()'方法中创建了一个新按钮,因此它已不可能被添加。 –

+0

这只是一个例子。想想像“为目录中的每个文件创建一个按钮”。您必须动态创建它们,有时在EDT中不可能。 – Steinliiippp

回答

0

不要在后台线程中创建UI。(最好)很少需要这样做。执行一些长时间运行的任务检索你需要为了创建UI,从任务返回数据,并创建任务的onSucceeded处理程序中的UI数据:

public class SomeControllerClass { 

    @FXML 
    private AnchorPane root ; 

    public void initialize() { 
     Task<SomeDataType> task = new MyTask(); 
     task.setOnSucceeded(e -> { 
      // this method executed on FX Application thread. 

      SomeDataType result = task.getValue(); 
      // now create UI and update root, using the data retrieved 
     }); 
     Thread thread = new Thread(task); 
     thread.start(); 
    } 

} 

public class MyTask extends Task<SomeDataType> { 

    @Override 
    public SomeDataType call() { 

     SomeDataType result = longRunningProcess(); 
     return result ; 
    } 
}