javafx CheckListView with custom objects to show particular property

3.6k views Asked by At

I have controlsfx CheckListView in my application. I am displaying my custom objects (eg: Employee). I have a list of employee objects created and wrapped in an observable list already. Now i set the observable list to my CheckListView.

checkListView.setItems(employeesObservableList);

Till here everything works fine.

Since i bound the employee objects, in the list view each checkbox value is my Employee object's toString(). I don't want the toString() value over there instead i want some other property of the employee (eno) to be displayed.

I don't see a cellValueFactory here and i don't know how to utilize the cellFactory to achieve my task, since CheckListView has its own cellFactory set already.

So my question is i want a CheckListView with checkbox values which i choose.

Thanks in advance!

1

There are 1 answers

1
James_D On BEST ANSWER

The list cell used by the CheckListView is a standard CheckBoxListCell from javafx.scene.control.cell. So you can override the cellFactory with something like:

checkListView.setCellFactory(listView -> new CheckBoxListCell(checkListView::getItemBooleanProperty) {
    @Override
    public void updateItem(Employee employee, boolean empty) {
        super.updateItem(employee, empty);
        setText(employee == null ? "" : employee.getEno());
    }
});

Note that CheckBoxListCell<T> has a constructor taking a Callback<T, BooleanProperty> specifying the boolean property for a check box displaying the item; CheckListView defines a method getItemBooleanProperty(T item) that returns exactly this value, so it can be passed directly to the constructor here using a method reference.

Here's a SSCCE:

import org.controlsfx.control.CheckListView;

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.stage.Stage;

public class CheckListViewTest extends Application {


    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Test");

        CheckListView<Employee> checkListView = new CheckListView<Employee>();

        ObservableList<Employee> oblist = FXCollections.observableArrayList();
        for (int i = 1; i <= 40; i++) {
            oblist.add(new Employee("Employee " + i, i));
        }
        checkListView.setItems(oblist);

        checkListView.setCellFactory(lv -> new CheckBoxListCell<Employee>(checkListView::getItemBooleanProperty) {
            @Override
            public void updateItem(Employee employee, boolean empty) {
                super.updateItem(employee, empty);
                setText(employee == null ? "" : String.format("Employee number: %04d", employee.getEno()));
            }
        });

        checkListView.getCheckModel().getCheckedIndices().addListener(new ListChangeListener<Integer>() {
            @Override
            public void onChanged(javafx.collections.ListChangeListener.Change<? extends Integer> c) {
                while (c.next()) {
                    if (c.wasAdded()) {
                        for (int i : c.getAddedSubList()) {
                            System.out.println(checkListView.getItems().get(i).getName() + " selected");
                        }
                    }
                    if (c.wasRemoved()) {
                        for (int i : c.getRemoved()) {
                            System.out.println(checkListView.getItems().get(i).getName() + " deselected");
                        }
                    }
                }
            }
        });


        Scene scene = new Scene(checkListView);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Employee {
        private final StringProperty name = new SimpleStringProperty();
        private final IntegerProperty eno = new SimpleIntegerProperty();
        public Employee(String name, int eno) {
            setName(name) ;
            setEno(eno);
        }
        public final StringProperty nameProperty() {
            return this.name;
        }

        public final String getName() {
            return this.nameProperty().get();
        }

        public final void setName(final String name) {
            this.nameProperty().set(name);
        }

        public final IntegerProperty enoProperty() {
            return this.eno;
        }

        public final int getEno() {
            return this.enoProperty().get();
        }

        public final void setEno(final int eno) {
            this.enoProperty().set(eno);
        }


    }

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

Which results in

enter image description here