Snow
Snow

Reputation: 25

How to count the checkbox in flow pane (Java)

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    System.out.println("confirmed");
    this.refreshData( e -> true);
    this.pieTriState.getData().forEach(this::clickOnPie);

    Arrays.stream(gList).forEach(e -> {
        var checkBox = new CheckBox(e.getState());
        checkBox.setPrefSize(60,15);
        this.fpStates.getChildren().add(checkBox);
        System.out.println(checkBox);

        checkBox.setOnAction((ActionEvent event) -> {
            if(checkBox.isSelected()){
                //I tried to count the checkbox by using this. but its not work for me
                for(int i =0; i <1; i++){
                    System.out.println(i);
                }
                System.out.println(checkBox.getText());

                //btnRefresh.setVisible(false);
                //lblStatus.setText("more than 4 states selected is invalid.");
            }
        });
    });

I am trying to count the checkbox. if 4 checkboxes are selected, so I can hide a button. But the problem is the checkbox is in the flow pane. So I don't know how to count it.

Upvotes: 0

Views: 182

Answers (2)

Sai Dandem
Sai Dandem

Reputation: 9959

Of the many ways, below is one of the approach you may give a try. The idea is:

  • create a counter and create a boolean listener to increment the counter and check if it satisfies the condition
  • add this listener all the checkboxes selected property.

Outside the loop you need to include the below code:

IntegerProperty count = new SimpleIntegerProperty();
ChangeListener<Boolean> selectedListener = (obs,old,selected)->{
    count.setValue(selected?count.get()+1:count.get()-1);
    if(count.get()>=4){
        // hide the button, set the error text
    }else{
        // unhide the button, clear the error text
    }
};

And in the loop, after the checkbox is created , add the listener to checkbox:

checkBox.selectedProperty().addListener(selectedListener);

Upvotes: 2

jewelsea
jewelsea

Reputation: 159466

This answer uses the same concept (a filtered list) as this solution to:

but without a backing model or table.

The solution:

  • creates a list of checkboxes.
  • defines an extractor on the checkbox list so that a list change event occurs when the selection property of any checkbox in the list changes.
  • creates a filtered list of selected checkboxes based on the list of all checkboxes.
  • binds integer properties to the size of the two lists.
  • displays labels that represent the size properties as text counts of the number of elements in each list.
  • places the checkboxes in a FlowPane.

To understand the approach in more detail, read the text accompanying the linked solution.

enter image description here

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class CheckApp extends Application {
    private static final int NUM_CHECKBOXES = 5;

    @Override
    public void start(Stage stage) {
        // lists to track checkboxes and selected checkboxes.
        ObservableList<CheckBox> checkBoxes = FXCollections.observableArrayList(
                c -> new Observable[] { c.selectedProperty() }
        );
        FilteredList<CheckBox> selectedCheckBoxes = checkBoxes.filtered(
                CheckBox::isSelected
        );

        // properties to track the size of the checkbox and selected checkbox lists.
        IntegerProperty numCheckboxes = new SimpleIntegerProperty();
        numCheckboxes.bind(Bindings.size(checkBoxes));
        IntegerProperty numSelectedCheckboxes = new SimpleIntegerProperty();
        numSelectedCheckboxes.bind(Bindings.size(selectedCheckBoxes));

        // create the checkboxes.
        for (int i = 0; i < NUM_CHECKBOXES; i++) {
            checkBoxes.add(new CheckBox("" + (i+1)));
        }

        // create a flow pane to hold the checkboxes and put them inside.
        FlowPane flowPane = new FlowPane(Orientation.VERTICAL, 10, 10);
        flowPane.setPadding(new Insets(10));
        flowPane.getChildren().addAll(checkBoxes);

        // create text labels for the checkbox and selected checkbox counts.
        Label numCheckboxesLabel = new Label();
        numCheckboxesLabel.textProperty().bind(
                numCheckboxes.asObject().asString()
        );
        Label numSelectedCheckboxesLabel = new Label();
        numSelectedCheckboxesLabel.textProperty().bind(
                numSelectedCheckboxes.asObject().asString()
        );

        // create some summary info
        GridPane summaryInfo = new GridPane();
        summaryInfo.setHgap(10);
        summaryInfo.setVgap(5);

        summaryInfo.addRow(0, new Label("# checkboxes:" ), numCheckboxesLabel);
        summaryInfo.addRow(1, new Label("# selected checkboxes:" ), numSelectedCheckboxesLabel);

        // layout the scene.
        final VBox layout = new VBox(
                10,
                summaryInfo,
                flowPane
        );
        layout.setPadding(new Insets(10));
        layout.setPrefHeight(200);

        stage.setScene(new Scene(layout));
        stage.show();
    }
}

Upvotes: 2

Related Questions