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

      Backports

        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:
                  6 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: