java - 如何确保按钮上的 Fxml 方法在监听器之前被调用?

标签 java events button javafx javafx-8

我有一个 Controller ,它启动一个名为file的新窗口:

// MainController.java
Stage primaryStage = new Stage();
FXMLLoader fx = new FXMLLoader(Paths.get("../file.fxml").toUri().toURL());
Scene scene = new Scene(fx.load());
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.centerOnScreen();

FileController control = (FileController ) fx.getController();
control.getValiderBE().setOnAction(event1 -> {
   System.out.prinln("here 1");
});

我在 FXML 文件 中有一个按钮:

// file.fxml, fx:controller="FileController"
<Button fx:id="validerBE" onMouseClicked="#validerClickBE" text="Valider">
</Button>

在其 Controller (FileController实例)中我得到:

FileController.java
@FXML
private Button validerBE;
@FXML
void validerClickBE(MouseEvent event) {
   System.out.prinln("here 2");
}
public Button getValiderBE() {
    return validerBE;
}

打印按以下顺序进行:这里 1 => 这里 2。并且 FileController 中的 sometines 方法甚至没有被调用^^ 就像如果事件在 here 1 调用中停止

但我会按照其他顺序,因为新的 window 将元素添加到列表中,并且第一个源 controller 应该刷新 TableView (添加操作后)

最佳答案

首先,请注意,您应该使用 onAction 来处理按钮点击,而不是 onMouseClicked。这样做的原因是,如果用户导航到按钮并激活它(通常使用空格键),或者不使用鼠标触发按钮(例如使用助记符),则 onMouseClicked 处理程序将获胜不被调用。

所以你应该有

<Button fx:id="validerBE" onAction="#validerClickBE" text="Valider" />

@FXML
void validerClickBE(ActionEvent event) {
   System.out.prinln("here 2");
}

对于事件排序:没有通用的方法来控制事件处理程序的调用顺序。有一些特殊情况,您可以在某些特定情况下利用它们,但通常不指定处理程序调用的顺序。因此,如果您有两个相互依赖的操作,则它们应该在同一个处理程序中执行。

无论如何,将 UI 控件暴露在 Controller 之外通常都是不好的做法 - 它违反了封装原则,并且会使代码更难维护。通常,您应该将数据模型传递给 Controller ​​,然后 Controller 可以调用它需要调用的数据模型上的任何操作。

至少,您可以定义一个字段来表示按下按钮时要执行的操作,并从现有处理程序中调用它,当然,正确的 MVC 方法更可取:

public class FileController {

    private Runnable onValidate = () -> {} ;

    public void setOnValidate(Runnable onValidate) {
        this.onValidate = onValidate ;
    }

    @FXML
    private void validerClickBE(ActionEvent event) {
        // whichever order you need....
        onValidate.run();
        System.out.println("here 2");
    }
}

然后当然

FXMLLoader fx = new FXMLLoader(Paths.get("../file.fxml").toUri().toURL());
Scene scene = new Scene(fx.load());
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.centerOnScreen();

FileController control = (FileController ) fx.getController();
control.setOnValidate(() -> System.out.println("here 1"));

关于java - 如何确保按钮上的 Fxml 方法在监听器之前被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48831988/

相关文章:

.net - Tridion:在事件系统中设置页面的元数据架构时出错

c# - WeakEventManager<TEventSource, TEventArgs> 和 PropertyChangedEventManager 导致内存泄漏

c# - 如何在不调用静态构造函数的情况下将处理程序绑定(bind)到静态事件?

actionscript-3 - AS3 错误 : '1172: Definition fl.controls:Button could not be found.'

java - Java 编译器是否优化了空的同步块(synchronized block)?

Java:非静态变量 this 不能从静态上下文中引用

java - 写入文件的 JUnit 测试在本地通过但在 Travis CI 上失败

Java - 只读取文件的第一行

java - 我的 fragment 内的按钮无法识别

javascript - JetStrap 中的函数调用