2016-01-27 117 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 ; 
    } 
}