我正在尝试在JavaFX中实现MVC解决方案,就像我以前使用swing一样。在我看来,存在一些差异。我通常的方法是有一个Starter class
来初始化view
和model
,并将它们传递给带有构造函数的controller
。然后,我会为view
提供对controller
的引用,以便它可以注册它以进行 UI 处理。然后,我将在我需要在controller
中访问的任何 GUI 元素上使用setActionCommand("xy");
。 setActionCommand();
ist 不可用于 JavaFX。我还看到过一些帖子,我应该对不同的元素使用不同的控制器,如下所示。
我开始按照习惯的方式实现它,现在我陷入了无法为按钮分配方法的地步。我的 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'"));
或类似东西的情况下区分按钮?
我也期待在CheckBox
和MenuItem
上使用它。
编辑:
通过将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
的问题。
JavaFX严重依赖lambda的使用。如果事件处理程序很简单(只有几行代码),并且不被任何其他控件重用,则可以这样做:
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);
或者,如果您想在控制器中定义它们,您也可以这样做,而无需控制器实现EventHandler
:
public void handleClickOnReset(Event event) {
System.out.println("Clicked on 'Filter zurücksetzen'");
}
然后像这样使用它:reset.setOnAction(controller::handleClickOnReset)
通常的方法是为每个控件使用不同的处理程序。通常,这是通过 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"));