JDK-8147820 : [TableView] getSelectedIndices: list from Change has unexpected side effects
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8u60
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-01-13
  • Updated: 2016-04-26
  • Resolved: 2016-04-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
I'm using a TableView with getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE) and getSelectionModel().setCellSelectionEnabled(false) and have added a ListChangeListener to getSelectionModel().getSelectedIndices(). The listener receives the Change c and prints the changed list twice with System.out.println(c.getList().toString() + " " + c.getList().toString()). Both strings should be equal, but in some cases they're not, for example [-1] [1]. The first string is wrong in this cases. Debugging shows a wrong index calculation in MultipleSelectionModelBase::createListFromBitSet.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. select the 2nd row with a mouse click
2. press shift + up
3. press shift + down

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The printed strings should be equal.
ACTUAL -
The printed strings are unequal.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javafx.application.Application;
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.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TableViewExample extends Application {

    private void init(Stage primaryStage) {
        VBox root = new VBox(2);
        primaryStage.setScene(new Scene(root, 300, 300));

        final ObservableList<TableViewExample.Person> data = FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new TableViewExample.Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new TableViewExample.Person("Ethan", "Williams", "ethan.williams@example.com"),
                new TableViewExample.Person("Emma", "Jones", "emma.jones@example.com"),
                new TableViewExample.Person("Michael", "Brown", "michael.brown@example.com"),
                new TableViewExample.Person("Jacob", "Smith", "jacob.smith@example.com"),
                new TableViewExample.Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new TableViewExample.Person("Ethan", "Williams", "ethan.williams@example.com"),
                new TableViewExample.Person("Emma", "Jones", "emma.jones@example.com"),
                new TableViewExample.Person("Michael", "Brown", "michael.brown@example.com"),
                new TableViewExample.Person("Jacob",     "Smith",    "jacob.smith@example.com" ),
                new TableViewExample.Person("Isabella",  "Johnson",  "isabella.johnson@example.com" ),
                new TableViewExample.Person("Ethan",     "Williams", "ethan.williams@example.com" ),
                new TableViewExample.Person("Emma",      "Jones",    "emma.jones@example.com" ),
                new TableViewExample.Person("Michael",   "Brown",    "michael.brown@example.com" ));

        TableColumn firstNameCol = new TableColumn();
        firstNameCol.setText("First");
        firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
        TableColumn lastNameCol = new TableColumn();
        lastNameCol.setText("Last");
        lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
        TableColumn emailCol = new TableColumn();
        emailCol.setText("Email");
        emailCol.setCellValueFactory(new PropertyValueFactory("email"));
        TableView tableView = new TableView();
        tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        tableView.getSelectionModel().setCellSelectionEnabled(false);
        tableView.setItems(data);
        tableView.getColumns().clear();
        tableView.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        tableView.getSelectionModel().getSelectedIndices().addListener(
                (ListChangeListener) c -> System.out.println(c.getList().toString() + " " + c.getList().toString())
        );

        root.getChildren().addAll(tableView);
    }

    public static class Person {

        private StringProperty firstName;
        private StringProperty lastName;
        private StringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public StringProperty firstNameProperty() {
            return firstName;
        }

        public StringProperty lastNameProperty() {
            return lastName;
        }

        public StringProperty emailProperty() {
            return email;
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        init(primaryStage);
        primaryStage.setTitle("Table Test " + System.getProperty("javafx.runtime.version"));
        primaryStage.show();
    }

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


Comments
This is no longer an issue due to the fix for JDK-8144501.
21-01-2016