有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在哪里向节点添加事件?

您能告诉我,我应该在哪里声明节点的事件侦听器吗?这些节点是在控制器类之外添加的

最好的方法是用这个例子来解释:

我有我的控制器:

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

我在这里干什么?我有一个FXML,根元素是锚烷。它具有id根。现在我开始了一个任务,在这个任务中,我向根节点添加了一个按钮。现在我想向按钮注册一个动作事件。我现在的问题是,我可以/应该在哪里注册听众。通常我在控制器中注册它们,但是在这里我不能这样做,因为按钮只存在于任务类中。我可以在Task类中注册它,但我认为它不能很好地扩展到大型应用程序。另一种方法是返回节点,这样我就可以在控制器类中访问它,但这里我必须检查它是否已经被添加(为此,我必须调用task.get(),这会停止我的应用程序。那么现在您能告诉我:为节点注册侦听器的最佳方法是什么


共 (1) 个答案

  1. # 1 楼答案

    不要在后台线程中创建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 ;
        }
    }