首页 > 解决方案 > 如何为许多 chechbox 制作一个动作事件?

问题描述

我在 JavaFX 中创建了一个应用程序,其中有很多选择框(大约 100 个)。单击它们中的每一个都会更改一个布尔变量的状态(选中 - 真,未选中 - 假)。我对每个选项框都有 ActionEvent,但我想制作支持所有选项的操作事件。

ActionEvent 之一如下所示:

public void onActionClick(ActionEvent actionEvent) {
    if(firstCheckbox.isSelected()){
        firstBooleanValue=true;
    } else {
        firstBooleanValue=false;
    }
}

第二个看起来相似:

public void onActionClick(ActionEvent actionEvent) {
    if(secondCheckbox.isSelected()){
        secondBooleanValue=true;
    } else {
        secondBooleanValue=false;
    }
}

我从朋友那里听说我应该使用 EventHandler 创建类并传递参数(复选框和布尔变量),但我不知道如何。有什么解决办法吗?

标签: javaeventsjavafx

解决方案


我从朋友那里听说我应该使用 EventHandler 创建类并传递参数(复选框和布尔变量)

除非您想为boolean变量使用容器类(例如BooleanProperty),否则实际上不可能以允许您编写变量的方式传递变量。你当然可以通过一个Consumer<Boolean>.

(理论上可以通过反射访问字段来写入值,但我强烈建议不要这样做。)

在事件处理程序中,您可以使用该source属性来获取触发更改的对象(CheckBox)。这一事实将允许您创建一个Map<CheckBox, Consumer<Boolean>>以使用相同的事件处理程序来处理事件,而无需测试与 100 CheckBoxes 的引用相等性。

private boolean a;
private boolean b;
private boolean c;
private Map<CheckBox, Consumer<Boolean>> eventMap = new HashMap<>();

private void comboAction(ActionEvent event) {
    CheckBox cb = (CheckBox) event.getSource();
    eventMap.get(cb).accept(cb.isSelected());
}

@Override
public void start(Stage primaryStage) {
    CheckBox cb1 = new CheckBox("a");
    CheckBox cb2 = new CheckBox("b");
    CheckBox cb3 = new CheckBox("c");

    // tell event handler what to do with the booleans
    eventMap.put(cb1, v -> a = v);
    eventMap.put(cb2, v -> b = v);
    eventMap.put(cb3, v -> c = v);

    // register event handlers
    EventHandler<ActionEvent> onAction = this::comboAction;

    for (CheckBox cb : eventMap.keySet()) {
        cb.setOnAction(onAction);
    }

    Button button = new Button("print");
    button.setOnAction(evt -> {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println("-------");
    });

    Scene scene = new Scene(new VBox(cb1, cb2, cb3, button));
    primaryStage.setScene(scene);
    primaryStage.show();
}

然而,一个类中有 100 个布尔字段这一事实表明存在设计问题。考虑将数据存储在不同的数据结构中,例如ListMap类似的数据结构。您还可以将 es 存储在这样的数据结构中,这样就不需要CheckBox使用事件处理程序;onAction您可以简单地检索该CheckBox属性的负责人并isSelected在需要该值时使用...


推荐阅读