2

I have a controlsfx CheckListView (even same issue with javafx ListView control) where i want to display RadioButtons instead of CheckBox. So i implemented custom cell factory by taking help from few javafx tutorials, and it is working. The problem is i selected the first radio button and scroll down a little so that few of my top radio button will be scrolled up and not visible now. Then again i scrolled up, the selection is gone now.

I debug the code understand that new cells are getting created every time and that leads to this issue but unfortunately can't figure out the solution.

I'm attaching a sample code which i got it from stack overflow which is having the same problem.

package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class RadioButtonListView extends Application {

    public static final ObservableList names = FXCollections.observableArrayList();
    private ToggleGroup group = new ToggleGroup();

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("List View Sample");

        final ListView listView = new ListView();
        listView.setPrefSize(200, 250);
        listView.setEditable(true);

        names.addAll("Adam", "Alex", "Alfred", "Albert", "Brenda", "Connie", "Derek", "Donny", "Lynne", "Myrtle", "Rose", "Rudolph", "Tony", "Trudy", "Williams", "Zach");

        listView.setItems(names);
        listView.setCellFactory(param -> new RadioListCell());
        StackPane root = new StackPane();
        root.getChildren().add(listView);
        primaryStage.setScene(new Scene(root, 200, 250));
        primaryStage.show();
    }

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

    private class RadioListCell extends ListCell<String> {
        @Override
        public void updateItem(String obj, boolean empty) {
            super.updateItem(obj, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                RadioButton radioButton = new RadioButton(obj);
                radioButton.setToggleGroup(group);
                // Add Listeners if any
                setGraphic(radioButton);
            }
        }
    }
}

Please need ur help in this.(I'm using javafx 8)

Saravana Kumar M
  • 460
  • 9
  • 19

1 Answers1

5

You should create a single radio button for the cell (instead of creating a new one each time updateItem(...) is called, and update its selected state in the updateItem(...) method using appropriate logic from your data representation.

private class RadioListCell extends ListCell<String> {

    private final RadioButton radioButton = new RadioButton();

    RadioListCell() {
        radioButton.setToggleGroup(group);
        // Add listeners here...
    }

    @Override
    public void updateItem(String obj, boolean empty) {
        super.updateItem(obj, empty);
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            radioButton.setText(obj);

            radioButton.setSelected(...);

            setGraphic(radioButton);
        }
    }
}

For example:

import java.util.Objects;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class RadioButtonListView extends Application {

    public static final ObservableList<String> names = FXCollections.observableArrayList();
    private ToggleGroup group = new ToggleGroup();

    private String selectedName ;

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("List View Sample");

        final ListView<String> listView = new ListView<>();
        listView.setPrefSize(200, 250);
        listView.setEditable(true);

        names.addAll("Adam", "Alex", "Alfred", "Albert", "Brenda", "Connie", "Derek", "Donny", "Lynne", "Myrtle", "Rose", "Rudolph", "Tony", "Trudy", "Williams", "Zach");

        listView.setItems(names);
        listView.setCellFactory(param -> new RadioListCell());
        StackPane root = new StackPane();
        root.getChildren().add(listView);
        primaryStage.setScene(new Scene(root, 200, 250));
        primaryStage.show();
    }

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

    private class RadioListCell extends ListCell<String> {

        private final RadioButton radioButton = new RadioButton();

        RadioListCell() {
            radioButton.setToggleGroup(group);
            radioButton.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
                if (isNowSelected) {
                    selectedName = getItem();
                }
            });
        }

        @Override
        public void updateItem(String obj, boolean empty) {
            super.updateItem(obj, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                radioButton.setText(obj);

                radioButton.setSelected(Objects.equals(obj, selectedName));

                setGraphic(radioButton);
            }
        }
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322
  • You saved my day. Thanks a lot. Actually i tried the same but somehow lost in the middle. I want to bring this to your knowledge. Your solution is working but if i select the first radio button, it is getting selected but also the 11th radio button's round (if 10 buttons are visible) is getting highlighted. (not selected but getting the focus). Not an issue for now. Thanks again. – Saravana Kumar M Nov 09 '16 at 14:04
  • 1
    @SaravanaKumar I can see why that would happen but I can't reproduce it reliably. Selection/focus in cells is kind of tricky. – James_D Nov 09 '16 at 14:20