簡體   English   中英

使用一個控制器處理多個JavaFX按鈕

[英]Handle multiple JavaFX buttons with one controller

我正在嘗試像以前一樣使用Swing在JavaFX中實現MVC解決方案。 在我看來,存在一些差異。 我通常的方法是擁有一個Starter class來初始化viewmodel ,並將它們都與構造函數一起傳遞給controller 然后,我將給該view一個對controller的引用,以便它可以為UI處理重新注冊它。 然后,我將使用setActionCommand("xy"); 在我需要在controller訪問的任何GUI元素上。 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'")); 或類似的東西?
我也期待在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塊。 Altough這可能是一個問題, 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);

或者,如果您想在Controller中定義它們,則也可以這樣做,而無需Controller實現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"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM