changeset 6913:da036c46b124

RT-36714: Flickering empty rows while updating a cell in a ListView
author jgiles
date Tue, 29 Apr 2014 10:13:39 +1200
parents 38c1ea45f8be
children 143503528295
files modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ListViewSkin.java modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TableViewSkinBase.java modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java
diffstat 3 files changed, 41 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ListViewSkin.java	Mon Apr 28 14:04:45 2014 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ListViewSkin.java	Tue Apr 29 10:13:39 2014 +1200
@@ -153,8 +153,13 @@
             while (c.next()) {
                 if (c.wasReplaced()) {
                     // RT-28397: Support for when an item is replaced with itself (but
-                    // updated internal values that should be shown visually)
-                    itemCount = 0;
+                    // updated internal values that should be shown visually).
+                    // This code was updated for RT-36714 to not update all cells,
+                    // just those affected by the change
+                    for (int i = c.getFrom(); i < c.getTo(); i++) {
+                        flow.setCellDirty(i);
+                    }
+
                     break;
                 } else if (c.getRemovedSize() == itemCount) {
                     // RT-22463: If the user clears out an items list then we
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TableViewSkinBase.java	Mon Apr 28 14:04:45 2014 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TableViewSkinBase.java	Tue Apr 29 10:13:39 2014 +1200
@@ -244,7 +244,17 @@
         while (c.next()) {
             if (c.wasReplaced()) {
                 // RT-28397: Support for when an item is replaced with itself (but
-                // updated internal values that should be shown visually)
+                // updated internal values that should be shown visually).
+
+                // The ListViewSkin equivalent code here was updated to use the
+                // flow.setDirtyCell(int) API, but it was left alone here, otherwise
+                // our unit test for RT-36220 fails as we do not handle the case
+                // where the TableCell gets updated (only the TableRow does).
+                // Ideally we would use the dirtyCell API:
+                //
+                // for (int i = c.getFrom(); i < c.getTo(); i++) {
+                //     flow.setCellDirty(i);
+                // }
                 itemCount = 0;
                 break;
             } else if (c.getRemovedSize() == itemCount) {
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Mon Apr 28 14:04:45 2014 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Apr 29 10:13:39 2014 +1200
@@ -57,6 +57,7 @@
 import sun.util.logging.PlatformLogger;
 import java.util.AbstractList;
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.List;
 
 /**
@@ -942,6 +943,22 @@
             lastHeight = -1;
         }
 
+        if (! dirtyCells.isEmpty()) {
+            int index;
+            while ((index = dirtyCells.nextSetBit(0)) != -1) {
+                T cell = cells.get(index);
+                // updateIndex(-1) works for TableView, but breaks ListView.
+                // For now, the TableView just does not use the dirtyCells API
+//                cell.updateIndex(-1);
+                cell.requestLayout();
+                dirtyCells.clear(index);
+            }
+
+            setMaxPrefBreadth(-1);
+            lastWidth = -1;
+            lastHeight = -1;
+        }
+
         final boolean hasSizeChange = sizeChanged;
         boolean recreatedOrRebuilt = needsRebuildCells || needsRecreateCells || sizeChanged;
 
@@ -2364,6 +2381,7 @@
     private boolean needsRebuildCells = false; // when cell contents have changed
     private boolean needsCellsLayout = false;
     private boolean sizeChanged = false;
+    private final BitSet dirtyCells = new BitSet();
     
     public void reconfigureCells() {
         needsReconfigureCells = true;
@@ -2385,6 +2403,11 @@
         requestLayout();
     }
 
+    public void setCellDirty(int index) {
+        dirtyCells.set(index);
+        requestLayout();
+    }
+
     private static final double GOLDEN_RATIO_MULTIPLIER = 0.618033987;
 
     private double getPrefBreadth(double oppDimension) {