【问题标题】:ToggleButtons in JavaFX with generic listenersJavaFX 中带有通用侦听器的切换按钮
【发布时间】:2017-07-21 22:04:16
【问题描述】:

我有 10 个切换按钮,例如 tb1、tb2、.. 等等。每一个都附有一个用户数据。我需要为单击和未单击按钮时要执行的操作(指令序列)附加一个侦听器。我希望监听器是通用的(可用于所有按钮)。

我面临的问题是,如何访问监听器中单击按钮的用户数据。请帮助解决这个问题。

@FXML
private ToggleButton tb1;
@FXML
private ToggleButton tb2;

String cpuLoad1 ="D:/myWorkspace/TestAttacks/input_folder/app_debug.apk";
String cpuLoad2 = "D:/myWorkspace/TestAttacks/input_folder/cpuLoad1.apk";


public void initialize(){

    tb1.setUserData(cpuLoad1);
    tb2.setUserData(cpuLoad2);

    ChangeListener clt1 = new ChangeListener() {
        public void changed(ObservableValue ov,
                Object toggle, Object new_toggle){
            if(new_toggle.equals(true)){

                /*how can I acces togglebutton userdata here. 
                 *I would like to pass it as arguement to this class object*/
                App load = new App(buttonClicked.getUserData());    //button clicked could tb1 or tb2
                load.installApp();
                load.launchApp();

            }else{
                System.out.println("OFF");
                /*how can I acces togglebutton userdata here. 
                 *I would like to pass it as arguement to this class object.*/
                App load = new App(buttonClicked.getUserData());
                load.unInstallApp();
            }
        }
    };

    tb1.selectedProperty().addListener(clt1);

    tb2.selectedProperty().addListener(clt1);

}

【问题讨论】:

标签: java javafx togglebutton


【解决方案1】:

您有多种选择。

选项1:ToggleButtons 收集到一个集合中,并在监听器中直接使用引用:

List<ToggleButton> toggles = new ArrayList<>(Arrays.asList(tb1, tb2));

for(ToggleButton toggle:toggles)
    toggle.selectedProperty().addListener((observable, oldValue, newValue) ->
        System.out.println(toggle.getText() + " - Selected: " + toggle.isSelected() + "; UserData: " + toggle.getUserData()));

选项2:您可以使用onActionProperty

tb1.setOnAction(e -> {
    ToggleButton toggle = (ToggleButton) e.getSource();
    System.out.println(toggle.getText() + " - Selected: " + toggle.isSelected()
            + "; UserData: " + toggle.getUserData());
});

选项3:如果需要存储监听器,可以实现自己的ChangeListener

public class Toggles extends Application {
    public static void main(String[] args) { launch(args); }

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox vBox = new VBox();
        for (int i = 0; i < 20; i++) {
            ToggleButton tb = new ToggleButton("ToggleButton" + i);
            tb.setUserData("UserData" + i);
            tb.selectedProperty().addListener(new ToggleButtonSourcedChangeListener(tb));
            vBox.getChildren().add(tb);
        }

        Scene scene = new Scene(new BorderPane(vBox), 320, 240);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private abstract static class SourcedChangeListener<T extends Node> implements ChangeListener<Boolean> {
        T source;

        SourcedChangeListener(T source) {
            this.source = source;
        }
    }

    private static class ToggleButtonSourcedChangeListener extends SourcedChangeListener<ToggleButton> {

        ToggleButtonSourcedChangeListener(ToggleButton source) {
            super(source);
        }

        @Override
        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
            System.out.println(source.getText() + " - Selected: " + source.isSelected()
                    + "; UserData: " + source.getUserData());
        }
    }
}

在这个 SSCE 中,我创建了一个抽象 SourceChangeListener,它可以通过具体实现进行扩展。泛型参数&lt;T extends Node&gt; 背后的意图是避免强制转换。

当您执行此代码并单击切换按钮时,输出将如下所示:

ToggleButton4 - Selected: true; UserData: UserData4
ToggleButton5 - Selected: true; UserData: UserData5
ToggleButton4 - Selected: false; UserData: UserData4
ToggleButton8 - Selected: true; UserData: UserData8
ToggleButton5 - Selected: false; UserData: UserData5
ToggleButton2 - Selected: true; UserData: UserData2

我建议使用selectedProperty 的选项之一,因为onActionProperty 仅在按下按钮(通过鼠标、触摸或键)或以编程方式调用fire() 方法时才会更改。即使您以编程方式更改选定状态,其他两个选项也将始终有效。

【讨论】:

  • 您不需要保留对切换的引用 - 所选属性(与任何其他属性一样)具有一个字段 bean,它是该属性的所有者。并且强烈建议不要使用 onAction,您已经提到了原因:-)
猜你喜欢
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 2023-03-30
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
相关资源
最近更新 更多