Zephyr
Zephyr

Reputation: 10253

JavaFX - Event handler for group of controls

I currently have an ArrayList of CheckBox controls. I am trying to capture any time a user checks or unchecks a box. However, I can't figure out how to do so without writing a separate handler for each and every checkbox, which really isn't feasible.

I've looked at other answers but they all see very specific to a particular project. Could someone just point me in the right directly on how to capture events for a whole group of controls?

End Goal: Determine within the handle() method which checkbox was checked (or unchecked) and act accordingly.

Thank you for your help, as I am a new coder!

Upvotes: 3

Views: 1486

Answers (2)

James_D
James_D

Reputation: 209330

The easiest way is to create a different handler for each checkbox:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class LotsOfCheckBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {
        List<CheckBox> checkBoxes = new ArrayList<>();
        int numBoxes = 20 ;

        VBox container = new VBox(5);

        for (int i = 1 ; i <= numBoxes ; i++) {
            checkBoxes.add(new CheckBox("Check box "+i));
        }

        container.getChildren().addAll(checkBoxes);

        for (CheckBox cb : checkBoxes) {
            cb.setOnAction(event -> handleCheckBox(cb));
        }

        Scene scene = new Scene(new ScrollPane(container), 200, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void handleCheckBox(CheckBox cb) {
        System.out.println(cb.getText() + (cb.isSelected() ? " selected" : " deselected"));
    }

    public static void main(String[] args) {
        launch(args);
    }
}

If you really want to use the same handler for all checkboxes, you can use Event.getSource() to get the source of the event, but you end up with some ugly downcasting:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class LotsOfCheckBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {
        List<CheckBox> checkBoxes = new ArrayList<>();
        int numBoxes = 20 ;

        VBox container = new VBox(5);

        for (int i = 1 ; i <= numBoxes ; i++) {
            checkBoxes.add(new CheckBox("Check box "+i));
        }

        container.getChildren().addAll(checkBoxes);

        EventHandler<ActionEvent> handler = event -> {
            CheckBox cb = (CheckBox) event.getSource() ;
            handleCheckBox(cb);
        };

        for (CheckBox cb : checkBoxes) {
            cb.setOnAction(handler);
        }

        Scene scene = new Scene(new ScrollPane(container), 200, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void handleCheckBox(CheckBox cb) {
        System.out.println(cb.getText() + (cb.isSelected() ? " selected" : " deselected"));
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Upvotes: 1

Nikolas
Nikolas

Reputation: 44378

Try to use the EventHandler for all the list of CheckBoxes.

EventHandler evChb = new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {  
        if (event.getSource() instanceof CheckBox) {
            CheckBox chb = (CheckBox) event.getSource();
            chb.setSelected(!chb.isSelected());
        }
    }
};

And add on action the event created above.

for(CheckBox ch: list) {
   ch.setOnAction(ecChb);
}

Upvotes: 1

Related Questions