java - 通过方法 DI 将事件处理程序从 Controller 传递到 View - JavaFX

标签 java model-view-controller event-handling javafx-2

我一直在尝试使用 JavaFX 构建一个简单的 GUI(我对 JavaFX 完全陌生),但我发现自己陷入了困境。在每个教程中,我发现事件处理都是在 UI 对象级别上完成的,主要是使用匿名内部类 - 我想要完成的是将事件处理程序移动到 Controller 类,并通过在 Controller 上调用的方法注入(inject)对它们的引用(和 View )实例化。

我的小GUI已正确构建并显示,引用确实已传递,但由于某种原因,handle()方法没有被调用,我找不到原因。

View :

//imports here
public class View extends Application implements ViewInterface, Runnable {
    private Menu fileMenu;
    private Menu storheouseMenu;
    private MenuBar menuBar;
    private Scene scene;
    private MenuItem exitItem;

    public View() {
        initialize();
    }

    public void initialize() {
        fileMenu = new Menu("Plik");
        storheouseMenu = new Menu("Magazyn");
        MenuItem exitItem = new MenuItem("Exit");
        MenuItem displayStorehouse = new MenuItem("Display");
        fileMenu.getItems().addAll(exitItem);
        storheouseMenu.getItems().add(0, displayStorehouse);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = new VBox();
        scene = new Scene(root, 400, 200);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Szefowa test");

        menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu, storheouseMenu);
        ((VBox) scene.getRoot()).getChildren().addAll(menuBar);

        primaryStage.setResizable(false);
        primaryStage.show();
    }

    public void addFileMenuListeners(EventHandler<ActionEvent> eventHandler) {
        exitItem = fileMenu.getItems().get(0);
        exitItem.setOnAction(eventHandler);
    }

    public void addStorehouseMenuListeners(EventHandler<ActionEvent> eventHandler) {
        MenuItem displayStorehouse = fileMenu.getItems().get(0);
        displayStorehouse.setOnAction(eventHandler);
    }

    public void displayMessage(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Ping");
        alert.setContentText(message);
    }
//other methods here

}

Controller :

package kitke.szefowa.controller;

//imports here

public class Controller implements ControllerInterface {
    private Model model;
    private View view;

    public Controller(Model model, View view) {
        this.model = model;
        this.view = view;
        this.view.addFileMenuListeners(new FileMenuListener());
        this.view.addStorehouseMenuListeners(new StorehouseMenuListener());
    }


    public class FileMenuListener implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent event) {
                       //do some stuff
        }
    }

    public class StorehouseMenuListener implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent event) {
            //do some stuff
            }
        }

    }
}

PS 我在使用 Swing 构建 GUI 时没有遇到这样的问题,因此问题与 JavaFX 有关。

最佳答案

我已经通过手动实例化测试了您的代码:

Controller controller = new Controller( this );

View.start()方法中。事件处理程序按预期工作,仅出现小问题。在 addFileMenuListeners() 和 addStorehouseMenuListeners() 方法中,您都将事件处理程序设置为相同的菜单项 fileMenu.getItems().get(0)。因此,依次调用这些方法,第二次调用将覆盖第一个调用的 setOnAction。

因此将 addStorehouseMenuListeners() 更改为:

public void addStorehouseMenuListeners( EventHandler<ActionEvent> eventHandler )
{
    MenuItem displayStorehouse = storheouseMenu.getItems().get(0);
    displayStorehouse.setOnAction( eventHandler );
}

关于java - 通过方法 DI 将事件处理程序从 Controller 传递到 View - JavaFX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29622022/

相关文章:

java - 如何为任何 JButton 添加两个不同的事件

c# - 按下WPF/MVVM右上角的关闭图标时如何处理关闭窗口?

java - 获取 Android 25 英里半径范围内的邮政编码

java - 如何在 Firestore 中批量写入后获取更新的文档引用?

c# - 为什么脚手架没有按预期工作?

python - wxPython 的 MVC 框架

model-view-controller - 业务逻辑是存在于模型中还是存在于 Controller 中?

Android:从应用程序类启动新 Activity

java - 无论如何让 Eclipse 将字符串转换为字符串?

java - 如何更改 Java 中 hashmap 列表中值的位置