JavaFX中的ToggleButtons具有通用侦听器

时间:2017-03-02 09:08:20

标签: java javafx togglebutton

我有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);

}

1 个答案:

答案 0 :(得分:1)

您有几种选择。

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

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,可以通过具体实现进行扩展。泛型参数<T extends Node>背后的意图是避免强制转换。

执行此代码并单击切换时,输出将如下:

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的其中一个选项,因为只有按下按钮(通过鼠标,触摸或按键)或者以编程方式调用{{1}时,onActionProperty才会更改}} 方法。即使您以编程方式更改选定状态,其他两个选项也将始终有效。