Question

The default selection model of JavaFX ListView seems to report wrong values to the listener in the Change object, if the selection mode is SelectionMode.MULTIPLE. Is my interpretation of Change incorrect?

I have a list view with items "Julia", "Ian", "Sue", etc. The code below generates the following output:

Clicking first item "Julia" ("Julia" is selected, output correct):

from 0, to 1, removed 0, added 1
was added
removed:
added:
    Julia
selected:
    Julia

Shift + ArrowDown ("Julia" and "Ian" are selected):

from 0, to 1, removed 0, added 1    <-- should be from 1, to 2
was added
removed:
added:
    Julia    <-- should be Ian
selected:
    Julia
    Ian

Shift + ArrowDown ("Julia", "Ian", and "Sue" are selected):

from 0, to 1, removed 0, added 1    <-- should be from 2, to 3
was added
removed:
added:
    Julia    <-- should be Sue
selected:
    Julia
    Ian
    Sue

Any explanation for this behavior?

public void start(Stage stage) {
    ObservableList<String> items = FXCollections.observableArrayList(
            "Julia", "Ian", "Sue", "Matthew", "Hannah", "Stephan", "Denise");
    ListView<String> listView = new ListView<>(items);

    MultipleSelectionModel<String> selectionModel = listView.getSelectionModel();
    selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
    ObservableList<String> selectedItems = selectionModel.getSelectedItems();

    selectedItems.addListener((ListChangeListener.Change<? extends String> c) -> {
        while (c.next()) {
            System.out.printf("from %d, to %d, removed %d, added %d\n", 
                    c.getFrom(), c.getTo(), c.getRemovedSize(), c.getAddedSize());
            if (c.wasAdded()) System.out.println("was added");
            if (c.wasRemoved()) System.out.println("was removed");
            if (c.wasPermutated()) System.out.println("was permutated");
            if (c.wasUpdated()) System.out.println("was updated");
            if (c.wasReplaced()) System.out.println("was replaced");
            System.out.println("removed:");
            for (String e : c.getRemoved()) {
                System.out.println("    " + e);
            }
            System.out.println("added:");
            for (String e : c.getAddedSubList()) {
                System.out.println("    " + e);
            }
            System.out.println("selected:");
            for (String e : selectedItems) {
                System.out.println("    " + e);
            }
            System.out.println();
        }
    });

    Scene scene = new Scene(listView, 300, 300);
    stage.setTitle("List View Sample");
    stage.setScene(scene);
    stage.show();
}
Was it helpful?

Solution

That looks like a bug, probably in the behavior class for ListView. You should file a bug report at https://javafx-jira.kenai.com

Note that

ObservableList<String> names = FXCollections.observableArrayList();
names.addListener((ListChangeListener.Change<? extends String> c) -> {
        while (c.next()) {
            System.out.printf("from %d, to %d, removed %d, added %d\n", 
                    c.getFrom(), c.getTo(), c.getRemovedSize(), c.getAddedSize());
            if (c.wasAdded()) System.out.println("was added");
            if (c.wasRemoved()) System.out.println("was removed");
            if (c.wasPermutated()) System.out.println("was permutated");
            if (c.wasUpdated()) System.out.println("was updated");
            if (c.wasReplaced()) System.out.println("was replaced");
            System.out.println("removed:");
            for (String e : c.getRemoved()) {
                System.out.println("    " + e);
            }
            System.out.println("added:");
            for (String e : c.getAddedSubList()) {
                System.out.println("    " + e);
            }
            System.out.println("selected:");
            for (String e : names) {
                System.out.println("    " + e);
            }
            System.out.println();
        }
    });
names.add("Julia");
names.add("Ian");
names.add("Sue");

behaves as you would expect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top