diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeViewSkin.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeViewSkin.java --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeViewSkin.java +++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeViewSkin.java @@ -35,7 +35,6 @@ import javafx.event.WeakEventHandler; import javafx.scene.Node; import javafx.scene.accessibility.Attribute; -import javafx.scene.accessibility.Role; import javafx.scene.control.*; import javafx.scene.control.TreeItem.TreeModificationEvent; import javafx.scene.input.MouseEvent; @@ -514,7 +513,7 @@ case FOCUS_ITEM: { FocusModel fm = getSkinnable().getFocusModel(); int focusedIndex = fm.getFocusedIndex(); - return flow.getCell(focusedIndex); + return flow.getPrivateCell(focusedIndex); } case ROW_AT_INDEX: { /* Note: Using getVisibleCell() is safer than getCell() for this case. @@ -522,14 +521,14 @@ * next sibling traversal to infinite loop. */ final int rowIndex = (Integer)parameters[0]; - return rowIndex < 0 ? null : flow.getVisibleCell(rowIndex); + return rowIndex < 0 ? null : flow.getPrivateCell(rowIndex); } case SELECTED_ROWS: { MultipleSelectionModel> sm = getSkinnable().getSelectionModel(); ObservableList indices = sm.getSelectedIndices(); List selection = new ArrayList<>(indices.size()); for (int i : indices) { - TreeCell row = flow.getCell(i); + TreeCell row = flow.getPrivateCell(i); if (row != null) selection.add(row); } return FXCollections.observableArrayList(selection); diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java +++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java @@ -864,6 +864,7 @@ } cells.clear(); pile.clear(); + releaseAllPrivateCells(); } else if (needsRebuildCells) { lastWidth = -1; lastHeight = -1; @@ -872,6 +873,7 @@ cells.get(i).updateIndex(-1); } addAllToPile(); + releaseAllPrivateCells(); } else if (needsReconfigureCells) { setMaxPrefBreadth(-1); lastWidth = -1; @@ -1708,6 +1710,57 @@ } /** + * This method is an experts-only method - if the requested index is not + * already an existing visible cell, it will create a cell for the + * given index and insert it into the sheet. From that point on it will be + * unmanaged, and is up to the caller of this method to manage it. + */ + T getPrivateCell(int index) { + T cell = null; + + // If there are cells, then we will attempt to get an existing cell + if (! cells.isEmpty()) { + // First check the cells that have already been created and are + // in use. If this call returns a value, then we can use it + cell = getVisibleCell(index); + if (cell != null) return cell; + } + + // check the existing sheet children + if (cell == null) { + for (int i = 0; i < sheetChildren.size(); i++) { + T _cell = (T) sheetChildren.get(i); + if (getCellIndex(_cell) == index) { + return _cell; + } + } + } + + if (cell == null) { + Callback createCell = getCreateCell(); + if (createCell != null) { + cell = createCell.call(this); + } + } + + if (cell != null) { + setCellIndex(cell, index); + resizeCellSize(cell); + cell.setVisible(false); + sheetChildren.add(cell); + privateCells.add(cell); + } + + return cell; + } + + private final List privateCells = new ArrayList<>(); + + private void releaseAllPrivateCells() { + sheetChildren.removeAll(privateCells); + } + + /** * Compute and return the length of the cell for the given index. This is * called both internally when adjusting by pixels, and also at times * by PositionMapper (see the getItemSize callback). When called by @@ -1948,7 +2001,8 @@ // if index is > firstIndex and < lastIndex then we can get the index if (index > firstIndex && index < lastIndex) { - return cells.get(index - firstIndex); + T cell = cells.get(index - firstIndex); + if (getCellIndex(cell) == index) return cell; } // there is no visible cell for the specified index