From 70f78c8568efa8720880f6fc5b5dc45896464b12 Mon Sep 17 00:00:00 2001 From: Jurgen <5031427+Jugen@users.noreply.github.com> Date: Wed, 13 Aug 2025 16:44:44 +0200 Subject: [PATCH 1/5] added refreshCell method --- .../java/org/fxmisc/flowless/CellListManager.java | 11 +++++++++++ src/main/java/org/fxmisc/flowless/VirtualFlow.java | 9 +++++++++ .../flowless/CellCreationAndLayoutEfficiencyTest.java | 8 ++++++++ 3 files changed, 28 insertions(+) diff --git a/src/main/java/org/fxmisc/flowless/CellListManager.java b/src/main/java/org/fxmisc/flowless/CellListManager.java index 5394466..532d57c 100644 --- a/src/main/java/org/fxmisc/flowless/CellListManager.java +++ b/src/main/java/org/fxmisc/flowless/CellListManager.java @@ -77,6 +77,17 @@ public C getCell(int itemIndex) { return cells.get(itemIndex); } + /** + * This is a noop on non visible items. For reusable Cells this will cause + * updateItem to be invoked on the next available pooled Cell. If a Cell is + * not available or reusable, a new Cell is created via the cell factory. + */ + public void refreshCell(int itemIndex) { + if (itemIndex >= 0 && itemIndex < cells.size() && cells.isMemoized(itemIndex)) { + cells.forget(itemIndex, itemIndex+1); + } + } + /** * Updates the list of cells to display * diff --git a/src/main/java/org/fxmisc/flowless/VirtualFlow.java b/src/main/java/org/fxmisc/flowless/VirtualFlow.java index 3de50c9..06ed55d 100644 --- a/src/main/java/org/fxmisc/flowless/VirtualFlow.java +++ b/src/main/java/org/fxmisc/flowless/VirtualFlow.java @@ -221,6 +221,15 @@ public Optional getCellIfVisible(int itemIndex) { return cellPositioner.getCellIfVisible(itemIndex); } + /** + * This is a noop on non visible items. For reusable Cells this will cause + * updateItem to be invoked on the next available pooled Cell. If a Cell is + * not available or reusable, a new Cell is created via the cell factory. + */ + public void refreshCell(int itemIndex) { + cellListManager.refreshCell(itemIndex); + } + /** * This method calls {@link #layout()} as a side-effect to insure * that the VirtualFlow is up-to-date in light of any changes diff --git a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java index 72b7ad3..a51dd86 100644 --- a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java +++ b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java @@ -71,6 +71,14 @@ public void updating_an_item_outside_viewport_does_not_create_or_lay_out_cell() assertEquals(0, cellLayouts.getAndReset()); } + @Test + public void refreshing_a_cell_in_viewport_creates_and_lays_out_once() { + // refresh a cell in the viewport + interact(() -> flow.refreshCell(10)); + assertEquals(1, cellCreations.getAndReset()); + assertEquals(1, cellLayouts.getAndReset()); + } + @Test public void deleting_an_item_in_viewport_only_creates_and_lays_out_cell_once() { // delete an item in the middle of the viewport From bd601d8ea3bc56dcd9b53d18fd3c97fa3915a4f5 Mon Sep 17 00:00:00 2001 From: Jurgen <5031427+Jugen@users.noreply.github.com> Date: Thu, 14 Aug 2025 16:01:15 +0200 Subject: [PATCH 2/5] Added refreshCells method --- .../org/fxmisc/flowless/CellListManager.java | 18 ++++++++++++++---- .../java/org/fxmisc/flowless/VirtualFlow.java | 4 ++-- .../CellCreationAndLayoutEfficiencyTest.java | 10 +++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/fxmisc/flowless/CellListManager.java b/src/main/java/org/fxmisc/flowless/CellListManager.java index 532d57c..e1264a7 100644 --- a/src/main/java/org/fxmisc/flowless/CellListManager.java +++ b/src/main/java/org/fxmisc/flowless/CellListManager.java @@ -82,10 +82,20 @@ public C getCell(int itemIndex) { * updateItem to be invoked on the next available pooled Cell. If a Cell is * not available or reusable, a new Cell is created via the cell factory. */ - public void refreshCell(int itemIndex) { - if (itemIndex >= 0 && itemIndex < cells.size() && cells.isMemoized(itemIndex)) { - cells.forget(itemIndex, itemIndex+1); - } + public void refreshCells(int fromItem, int toItem) { + int start = Math.min( fromItem, toItem ); + int end = Math.max( fromItem, toItem ); + + IndexRange memorizedRange = cells.getMemoizedItemsRange(); + int min = memorizedRange.getStart(); + int max = memorizedRange.getEnd(); + + start = Math.max( start, min ); + end = Math.min( end, max ); + + if ( start < max && end > min ) { + cells.forget(start, end); + } } /** diff --git a/src/main/java/org/fxmisc/flowless/VirtualFlow.java b/src/main/java/org/fxmisc/flowless/VirtualFlow.java index 06ed55d..03d278f 100644 --- a/src/main/java/org/fxmisc/flowless/VirtualFlow.java +++ b/src/main/java/org/fxmisc/flowless/VirtualFlow.java @@ -226,8 +226,8 @@ public Optional getCellIfVisible(int itemIndex) { * updateItem to be invoked on the next available pooled Cell. If a Cell is * not available or reusable, a new Cell is created via the cell factory. */ - public void refreshCell(int itemIndex) { - cellListManager.refreshCell(itemIndex); + public void refreshCells(int fromIndex, int toIndex) { + cellListManager.refreshCells(fromIndex, toIndex); } /** diff --git a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java index a51dd86..d767cf6 100644 --- a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java +++ b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java @@ -72,11 +72,11 @@ public void updating_an_item_outside_viewport_does_not_create_or_lay_out_cell() } @Test - public void refreshing_a_cell_in_viewport_creates_and_lays_out_once() { - // refresh a cell in the viewport - interact(() -> flow.refreshCell(10)); - assertEquals(1, cellCreations.getAndReset()); - assertEquals(1, cellLayouts.getAndReset()); + public void refreshing_cells_in_viewport_creates_and_lays_them_out_once() { + // refresh cells in the viewport + interact(() -> flow.refreshCells(10,12)); + assertEquals(2, cellCreations.getAndReset()); + assertEquals(2, cellLayouts.getAndReset()); } @Test From 5bdb6ed16f52841e9f3abc5ca380263ad22d4b2c Mon Sep 17 00:00:00 2001 From: Jurgen <5031427+Jugen@users.noreply.github.com> Date: Fri, 15 Aug 2025 14:24:36 +0200 Subject: [PATCH 3/5] Fixed refreshCells interval error --- .../org/fxmisc/flowless/CellListManager.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/fxmisc/flowless/CellListManager.java b/src/main/java/org/fxmisc/flowless/CellListManager.java index e1264a7..a845009 100644 --- a/src/main/java/org/fxmisc/flowless/CellListManager.java +++ b/src/main/java/org/fxmisc/flowless/CellListManager.java @@ -81,21 +81,21 @@ public C getCell(int itemIndex) { * This is a noop on non visible items. For reusable Cells this will cause * updateItem to be invoked on the next available pooled Cell. If a Cell is * not available or reusable, a new Cell is created via the cell factory. + * @param fromItem - the start index, inclusive. + * @param toItem - the end index, exclusive. */ public void refreshCells(int fromItem, int toItem) { - int start = Math.min( fromItem, toItem ); - int end = Math.max( fromItem, toItem ); + if (fromItem >= toItem) throw new IllegalArgumentException( + String.format("To must be greater than from. from=%s to=%s", fromItem, toItem) + ); - IndexRange memorizedRange = cells.getMemoizedItemsRange(); - int min = memorizedRange.getStart(); - int max = memorizedRange.getEnd(); - - start = Math.max( start, min ); - end = Math.min( end, max ); + IndexRange memorizedRange = cells.getMemoizedItemsRange(); + fromItem = Math.max( fromItem, memorizedRange.getStart() ); + toItem = Math.min( toItem, memorizedRange.getEnd() ); - if ( start < max && end > min ) { - cells.forget(start, end); - } + if (fromItem < toItem) { + cells.forget(fromItem, toItem); + } } /** From 6c79a55802b7ea59130023a1a24e96deb20d2979 Mon Sep 17 00:00:00 2001 From: Jurgen <5031427+Jugen@users.noreply.github.com> Date: Fri, 15 Aug 2025 14:49:26 +0200 Subject: [PATCH 4/5] Updated JavaDoc --- src/main/java/org/fxmisc/flowless/VirtualFlow.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/fxmisc/flowless/VirtualFlow.java b/src/main/java/org/fxmisc/flowless/VirtualFlow.java index 03d278f..af4a7ae 100644 --- a/src/main/java/org/fxmisc/flowless/VirtualFlow.java +++ b/src/main/java/org/fxmisc/flowless/VirtualFlow.java @@ -225,9 +225,11 @@ public Optional getCellIfVisible(int itemIndex) { * This is a noop on non visible items. For reusable Cells this will cause * updateItem to be invoked on the next available pooled Cell. If a Cell is * not available or reusable, a new Cell is created via the cell factory. + * @param fromIndex - the start index, inclusive. + * @param toIndex - the end index, exclusive. */ public void refreshCells(int fromIndex, int toIndex) { - cellListManager.refreshCells(fromIndex, toIndex); + cellListManager.refreshCells(fromIndex, toIndex); } /** From cda9fd79d7192f0872553c1b1c97e1ef016c4b0f Mon Sep 17 00:00:00 2001 From: Jurgen <5031427+Jugen@users.noreply.github.com> Date: Fri, 15 Aug 2025 16:07:48 +0200 Subject: [PATCH 5/5] Added another test --- .../flowless/CellCreationAndLayoutEfficiencyTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java index d767cf6..ad5d909 100644 --- a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java +++ b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java @@ -78,6 +78,13 @@ public void refreshing_cells_in_viewport_creates_and_lays_them_out_once() { assertEquals(2, cellCreations.getAndReset()); assertEquals(2, cellLayouts.getAndReset()); } + @Test + public void refreshing_cells_outside_viewport_does_not_create_or_lay_them_out() { + // refresh 10 cells, 5 in and 5 outside the viewport + interact(() -> flow.refreshCells(20,30)); + assertEquals(5, cellCreations.getAndReset()); + assertEquals(5, cellLayouts.getAndReset()); + } @Test public void deleting_an_item_in_viewport_only_creates_and_lays_out_cell_once() {