Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8122970

CheckBoxTableCell unexpected behavior when TableView is sorted (items indexes change)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 8
    • 8
    • javafx
    • Windows 8 64bit

      UPDATE:
      Turned out that the bug is also present when adding/removing items. It seems that whenever indexes change, the bindings get corrupted.

      When the TableView is sorted by clicking on a column header, the checkboxes behavior becomes unexpected. If you check one of them, another one seems to be bound to it, and becomes selected as well.

      Before sorting the TableView, everything work as expected, but once a sort has been triggered, the behavior is unexpected.

      Here is an SSCCE:

      import javafx.application.Application;
      import javafx.beans.property.BooleanProperty;
      import javafx.beans.property.SimpleBooleanProperty;
      import javafx.beans.property.SimpleStringProperty;
      import javafx.beans.property.StringProperty;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.collections.transformation.SortedList;
      import javafx.scene.Scene;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableView;
      import javafx.scene.control.cell.CheckBoxTableCell;
      import javafx.scene.control.cell.TextFieldTableCell;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;

      /**
       * Author: Anas H. Sulaiman (anas@ahs.pw)
       */
      public class CheckBoxTableCellBug extends Application {
          public static void main(String[] args) {
              launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
              ObservableList<Person> persons = FXCollections.observableArrayList();
              persons.add(new Person("Sami", "Haddad", false));
              persons.add(new Person("Ahmed", "Hasan", true));
              persons.add(new Person("Rami", "Kassar", true));
              persons.add(new Person("Nehad", "Hamad", false));
              persons.add(new Person("Jamal", "Raei", true));
              persons.add(new Person("Ameer", "Raji", true));
              persons.add(new Person("Tahseen", "Muhsen", true));

              SortedList<Person> sortedList = new SortedList<>(persons);
              TableView<Person> table = new TableView<>(sortedList);
              sortedList.comparatorProperty().bind(table.comparatorProperty());
              table.setEditable(true);
              table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

              TableColumn<Person, String> colFirstName = new TableColumn<>("First Name");
              colFirstName.setCellValueFactory(p -> p.getValue().firstName);
              colFirstName.setCellFactory(TextFieldTableCell.forTableColumn());
              colFirstName.setOnEditCommit(event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).firstName.set(event.getNewValue()));

              TableColumn<Person, String> colLastName = new TableColumn<>("Last Name");
              colLastName.setCellValueFactory(p -> p.getValue().lastName);
              colLastName.setCellFactory(TextFieldTableCell.forTableColumn());
              colLastName.setOnEditCommit(event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).lastName.set(event.getNewValue()));

              TableColumn<Person, Boolean> colInvited = new TableColumn<>("Invited");
              colInvited.setCellValueFactory(p -> p.getValue().invited);
              colInvited.setCellFactory(CheckBoxTableCell.forTableColumn(colInvited));

              table.getColumns().addAll(colFirstName, colLastName, colInvited);

              stage.setScene(new Scene(new StackPane(table)));
              stage.setTitle("CheckBoxTableCell Bug");
              stage.show();
          }

          class Person {
              public StringProperty firstName;
              public StringProperty lastName;
              public BooleanProperty invited;

              public Person() {
                  this.firstName = new SimpleStringProperty("");
                  this.lastName = new SimpleStringProperty("");
                  this.invited = new SimpleBooleanProperty(false);
              }

              public Person(String fname, String lname, boolean invited) {
                  this();
                  this.firstName.set(fname);
                  this.lastName.set(lname);
                  this.invited.set(invited);
              }
          }
      }

      How to reproduce the bug:

          1. Click once on the header of the "First Name" column to sort the table
          2. Try selecting the first check box in the "Invited" column
          3. Try selecting the third check box in the "Invited" column

      As expected, the bug is also present in Ensemble (The application that comes with JavaFX Samples).

      (First mentioned here: http://stackoverflow.com/questions/18960799/)

            jgiles Jonathan Giles
            asulaimanjfx Anas H. Sulaiman (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: