diff --git a/src/main/java/org/fxmisc/flowless/CellListManager.java b/src/main/java/org/fxmisc/flowless/CellListManager.java index 5394466..a845009 100644 --- a/src/main/java/org/fxmisc/flowless/CellListManager.java +++ b/src/main/java/org/fxmisc/flowless/CellListManager.java @@ -77,6 +77,27 @@ 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. + * @param fromItem - the start index, inclusive. + * @param toItem - the end index, exclusive. + */ + public void refreshCells(int fromItem, int 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(); + fromItem = Math.max( fromItem, memorizedRange.getStart() ); + toItem = Math.min( toItem, memorizedRange.getEnd() ); + + if (fromItem < toItem) { + cells.forget(fromItem, toItem); + } + } + /** * 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..af4a7ae 100644 --- a/src/main/java/org/fxmisc/flowless/VirtualFlow.java +++ b/src/main/java/org/fxmisc/flowless/VirtualFlow.java @@ -221,6 +221,17 @@ 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. + * @param fromIndex - the start index, inclusive. + * @param toIndex - the end index, exclusive. + */ + public void refreshCells(int fromIndex, int toIndex) { + cellListManager.refreshCells(fromIndex, toIndex); + } + /** * 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..ad5d909 100644 --- a/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java +++ b/src/test/java/org/fxmisc/flowless/CellCreationAndLayoutEfficiencyTest.java @@ -71,6 +71,21 @@ public void updating_an_item_outside_viewport_does_not_create_or_lay_out_cell() assertEquals(0, cellLayouts.getAndReset()); } + @Test + 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 + 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() { // delete an item in the middle of the viewport