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

Single cell selection flickers when adding data to TableView

    Details

    • Subcomponent:
    • Introduced In Version:
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) Client VM (build 25.121-b13, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Darwin Sams-MacBook-Pro.local 16.5.0 Darwin Kernel Version 16.5.0: Fri Mar 3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64

      macOS 10.12
      Windows 10

      A DESCRIPTION OF THE PROBLEM :
      In a JavaFX TableView with Single Cell Selection enabled, the currently selected cell will flicker when data is added to the TableView

      It seems to only affect Single Cell Selection, when this is disabled there's no flickering. I think it's to do with the cell objects being recycled and moved around the TableView

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the included test case, and select a cell. The test case periodically adds data, and you'll see the flickering

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The currently selected cell remains selected with no flickering
      ACTUAL -
      The currently selected cell flickers

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.Random;

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.beans.property.ReadOnlyStringWrapper;
      import javafx.collections.FXCollections;
      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.layout.BorderPane;
      import javafx.stage.Stage;
      import javafx.util.Callback;

      public class SelectionBug extends Application
      {
          public static void main(
              String[] args)
          {
              Application.launch(args);
          }
          
          @Override
          public void start(
              Stage primaryStage) throws Exception
          {
              final ObservableList<DummyData> list = FXCollections.observableArrayList();
              
              final TableView<DummyData> tableView = new TableView<>(list);
              tableView.getColumns().add(createColumn(item -> item.getColumn1()));
              tableView.getColumns().add(createColumn(item -> item.getColumn2()));
              tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
              tableView.getSelectionModel().setCellSelectionEnabled(true);
              
              final Thread thread = new Thread(() ->
              {
                  while (true)
                  {
                      Platform.runLater(() -> list.add(new DummyData()));
                      
                      try
                      {
                          Thread.sleep(1000);
                      }
                      catch (InterruptedException e)
                      {
                          //do nothing
                      }
                  }
              });
              thread.setDaemon(true);
              thread.start();
              
              final BorderPane root = new BorderPane();
              root.setCenter(tableView);
              primaryStage.setScene(new Scene(root, 500, 500));
              primaryStage.show();
          }
          
          private TableColumn<DummyData, String> createColumn(
              final Callback<DummyData, String> dataGetter)
          {
              final TableColumn<DummyData, String> column = new TableColumn<>();
              column.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(dataGetter.call(cellData.getValue())));
              return column;
          }
          
          private static class DummyData
          {
              private final String mColumn1;
              private final String mColumn2;
              
              public DummyData()
              {
                  final Random ramdom = new Random();
                  mColumn1 = Integer.toString(ramdom.nextInt(1000));
                  mColumn2 = Integer.toString(ramdom.nextInt(1000));
              }
              
              public String getColumn1()
              {
                  return mColumn1;
              }
              
              public String getColumn2()
              {
                  return mColumn2;
              }
          }

      }

      ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                aghaisas Ajit Ghaisas
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated: