【问题标题】:Which is the correct way to add a huge amount of listeners to different elements in java?在 java 中向不同元素添加大量侦听器的正确方法是什么?
【发布时间】:2022-11-16 22:23:48
【问题描述】:

我在处理大量节点的 JavaFX 程序中有一个控制器类。我创建了一个方法addEventListeners,它看起来像:

    cleanButton.setOnAction(e -> {
        ...
    });

    advSett.setOnAction(e -> {
        ...
    });

    imageLoaderItem.setOnAction(e -> {
        ...
    });

    outputButton.setOnAction(e -> {
        ...
    });

对于控制器处理的每个元素,依此类推。 这个方法占用了 300 行代码,使得控制器类非常混乱。我想知道,是否有更简洁的方式来添加听众?

【问题讨论】:

  • 每个听众都做同样的事情吗?然后只需定义一个包含侦听器的变量并将其作为参数传递。如果它不一样但有一个模式,您可以创建一个方法来返回侦听器的变体。如果它们都不同,您显然必须在某处为每个代码编写代码。您使用的 lambda 语法已经非常简洁(对于 Java)。
  • 您可以执行多种操作,具体取决于您的事件处理程序逻辑的确切性质。除了@Jorn 的(优秀)建议外,您还可以通过为每个操作定义方法来使代码(也许)更整洁,然后将注册设为单行(例如cleanButton.setOnAction(e -> clean());)或直接引用这些方法来自 FMXL。如果操作密切相关,这也会有所帮助:private void processNumericInput(int value) { ... }button1.setOnAction(e -> processNumericInput(1)); 等。
  • 如果问题真的只是您拥有大量控件,请考虑将 FXML 分解为更小的、逻辑上不同的 FXML 文件,每个文件都有自己的控制器。

标签: java javafx listener


【解决方案1】:

正如 cmets 中正确指出的那样,当您遇到此类问题时,将您的控制器拆分成几个较小的控制器通常是个好主意。尽管如此,还是有一些方法可以避免重复相同或相似的指令。如果你所有的按钮/节点都做同样的事情,你可以简单地这样做:

private void addEventListener(final ButtonBase element) {
    element.setOnAction(e -> {
        //do the thing
    });
}

如果你的大多数节点都做同样的事情,只有两三个不同,那么你可以像这样扩展相同的方法:

private void addEventListener(final ButtonBase element) {
        if (element == cleanButton) {
            element.setOnAction(e -> {
                //do the thing
            });
        } else {
            element.setOnAction(e -> {
                //do the other thing
            });
        }
}

如果你有可识别的按钮组做同样的事情,比如 A 组做 x,B 组做 y,那么你可以将它们分别添加到一个集合中并以这种方式处理它们

private void addEventListener(final ButtonBase element) {
        if (groupA.contains(element)) {
            element.setOnAction(e -> {
                //do the thing for A
            });
        } else {
            element.setOnAction(e -> {
                //do the other thing
            });
        }
    }

最后,您还可以将其翻转过来。如果共同点是事件,而不是节点,那么您还可以重构您的函数以处理事件来自特定元素的事件

private void handleButtonClicks(final javafx.event.ActionEvent mouseEvent) {
        switch (mouseEvent.getSource()) {
            case cleanButton:
                // and so on
            default:
     }
}

【讨论】:

  • 不幸的是,每个听众的所作所为各不相同。但我没有考虑将控制器拆分成更小的控制器。答案被采纳!
猜你喜欢
  • 2019-03-25
  • 2018-01-11
  • 1970-01-01
  • 2021-10-14
  • 2015-10-20
  • 2016-11-09
  • 2020-03-06
  • 2023-01-19
  • 2015-08-16
相关资源
最近更新 更多