【问题标题】:Handle multiple JavaFX buttons with one controller使用一个控制器处理多个 JavaFX 按钮
【发布时间】:2016-03-17 11:23:23
【问题描述】:

我正在尝试在 JavaFX 中实现 MVC 解决方案,就像我以前使用 swing 一样。在我看来,存在一些差异。我通常的方法是使用Starter class 来初始化viewmodel,并使用构造函数将它们都传递给controller。然后我会给view 一个对controller 的引用,以便它可以注册它以进行UI 处理。然后我会在controller 中需要访问的任何GUI 元素上使用setActionCommand("xy");setActionCommand(); 不适用于 JavaFX。我还看到了一些帖子,我应该对不同的元素使用不同的控制器,如 here 所示。
我开始按照习惯实现它,但现在我陷入无法为按钮分配方法的地步。我的 3 个按钮如下所示:

Button newGraph = new Button("Neuer Graph");
newGraph.setOnAction(controller);
Button extendGraph = new Button("Graph erweitern");
extendGraph.setOnAction(controller);
Button reset = new Button("Filter zurücksetzen");
reset.setOnAction(controller);

我的控制器如下所示:

public class GraphController implements EventHandler {
    private GraphHandler graphHandler; //model
    private GraphView graphView; //view

    public GraphController(GraphHandler graphHandler, GraphView graphView, Stage stage){
        this.graphHandler = graphHandler;
        this.graphView = graphView;
        graphView.registerController(this); //introduce controller to view
        graphView.start(stage); //start the main frame
    }

    @Override
    public void handle(Event event) {
        System.out.println(event.getSource().toString());
    }
}

打印哪个:

Button@1f74b31a[styleClass=button]'Filter zurücksetzen'
Button@37901011[styleClass=button]'Neuer Graph'
Button@39afc158[styleClass=button]'Graph erweitern'

如何在不使用if(event.getSource().toString().equals("Button@1f74b31a[styleClass=button]'Filter zurücksetzen'")); 或类似的东西的情况下区分按钮?
我也期待在CheckBoxMenuItem 上使用它。

编辑:
通过将sender 解析为按钮部分解决了它。

@Override
    public void handle(Event event) {
        try {
            Button sender = (Button) event.getSource();
            switch (sender.getText()){
                case "Filter zurücksetzen":
                    System.out.println("reset");
                    break;
                case "Neuer Graph":
                    System.out.println("new");
                    break;
                case "Graph erweitern":
                    System.out.println("extend");
                    break;
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

有没有更通用的方法?由于我也不想解析其他事件,这将导致更多 try, catch 块。虽然这可能是 codereview 在这一点上的问题..

【问题讨论】:

  • 通常的方法是对每个控件使用不同的处理程序。你有什么不想这样做的原因吗?
  • 我不希望我的应用程序充满了controller 类并且仍然使用mvc patter,但如前所述,我还不知道如何在JavaFX 中正确执行此操作。
  • 好吧,您不必为每个类都设置不同的类,只需使用不同的实例即可。或者只是使用 lambda 表达式(请参阅 hostz 的答案)来最小化代码开销(或匿名内部类,尽管与 lambda 相比这些是冗长的)。

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


【解决方案1】:

JavaFX 在很大程度上依赖于 lambdas 的使用。如果事件处理程序很简单(只有几行代码)并且没有被任何其他控件重用,您可以这样做:

Button reset = new Button("Filter zurücksetzen");
reset.setOnAction(event -> System.out.println("Clicked on 'Filter zurücksetzen'"));

如果重复使用相同的简单 lambda 表达式,您可以单独定义并重复使用它:

EventHanlder handler = event -> System.out.println("Clicked on 'Filter zurücksetzen'");
Button reset = new Button("Filter zurücksetzen");
reset.setOnAction(handler);

或者,如果您想在 Controller 中定义它们,您也可以这样做,而无需 Controller 实现 EventHandler

public void handleClickOnReset(Event event) {
    System.out.println("Clicked on 'Filter zurücksetzen'");
}

然后像这样使用它: reset.setOnAction(controller::handleClickOnReset)

【讨论】:

  • 听起来不错,我试试看:)如果成功我会标记它
【解决方案2】:

通常的方法是为每个控件使用不同的处理程序。通常这是使用 lambda 表达式完成的,如 hotzst 的回答;如果您更喜欢更传统的方法,您也可以将一个或多个参数添加到您的独立类并使用它的不同实例。

public class ButtonHandler implements EventHandler<ActionEvent> {

    private final String message ;

    public ButtonHandler(String message) {
        this.message = message ;
    }

    @Override
    public handle(ActionEvent event) {
        System.out.println(message);
    }
}

然后

Button newGraph = new Button("Neuer Graph");
newGraph.setOnAction(new ButtonHandler("New"));
Button extendGraph = new Button("Graph erweitern");
extendGraph.setOnAction(new ButtonHandler("extend"));
Button reset = new Button("Filter zurücksetzen");
reset.setOnAction(new ButtonHandler("reset"));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多