modules/controls/src/main/java/javafx/scene/control/skin/TreeTableViewSkin.java
Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -21,15 +21,18 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package com.sun.javafx.scene.control.skin;
+package javafx.scene.control.skin;
import com.sun.javafx.collections.NonIterableChange;
+import com.sun.javafx.scene.control.Properties;
import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import com.sun.javafx.scene.control.skin.Utils;
import javafx.event.WeakEventHandler;
import javafx.scene.control.*;
import com.sun.javafx.scene.control.behavior.TreeTableViewBehavior;
@@ -51,270 +54,382 @@
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
-public class TreeTableViewSkin<S> extends TableViewSkinBase<S, TreeItem<S>, TreeTableView<S>, TreeTableViewBehavior<S>, TreeTableRow<S>, TreeTableColumn<S,?>> {
+/**
+ * Default skin implementation for the {@link TreeTableView} control.
+ *
+ * @see TreeTableView
+ * @since 9
+ */
+public class TreeTableViewSkin<T> extends TableViewSkinBase<T, TreeItem<T>, TreeTableView<T>, TreeTableRow<T>, TreeTableColumn<T,?>> {
+
+ /***************************************************************************
+ * *
+ * Private Fields *
+ * *
+ **************************************************************************/
+
+ private TreeTableViewBackingList<T> tableBackingList;
+ private ObjectProperty<ObservableList<TreeItem<T>>> tableBackingListProperty;
+ private WeakReference<TreeItem<T>> weakRootRef;
+ private final TreeTableViewBehavior<T> behavior;
+
+
+
+ /***************************************************************************
+ * *
+ * Listeners *
+ * *
+ **************************************************************************/
+
+ private EventHandler<TreeItem.TreeModificationEvent<T>> rootListener = e -> {
+ if (e.wasAdded() && e.wasRemoved() && e.getAddedSize() == e.getRemovedSize()) {
+ // Fix for RT-14842, where the children of a TreeItem were changing,
+ // but because the overall item count was staying the same, there was
+ // no event being fired to the skin to be informed that the items
+ // had changed. So, here we just watch for the case where the number
+ // of items being added is equal to the number of items being removed.
+ rowCountDirty = true;
+ getSkinnable().requestLayout();
+ } else if (e.getEventType().equals(TreeItem.valueChangedEvent())) {
+ // Fix for RT-14971 and RT-15338.
+ needCellsRebuilt = true;
+ getSkinnable().requestLayout();
+ } else {
+ // Fix for RT-20090. We are checking to see if the event coming
+ // from the TreeItem root is an event where the count has changed.
+ EventType<?> eventType = e.getEventType();
+ while (eventType != null) {
+ if (eventType.equals(TreeItem.<T>expandedItemCountChangeEvent())) {
+ rowCountDirty = true;
+ getSkinnable().requestLayout();
+ break;
+ }
+ eventType = eventType.getSuperType();
+ }
+ }
- public TreeTableViewSkin(final TreeTableView<S> treeTableView) {
- super(treeTableView, new TreeTableViewBehavior<S>(treeTableView));
+ // fix for RT-37853
+ getSkinnable().edit(-1, null);
+ };
+
+ private WeakEventHandler<TreeModificationEvent<T>> weakRootListener;
+
+
+
+ /***************************************************************************
+ * *
+ * Constructors *
+ * *
+ **************************************************************************/
- this.treeTableView = treeTableView;
- this.tableBackingList = new TreeTableViewBackingList<S>(treeTableView);
- this.tableBackingListProperty = new SimpleObjectProperty<ObservableList<TreeItem<S>>>(tableBackingList);
+ /**
+ * Creates a new TreeTableViewSkin instance, installing the necessary child
+ * nodes into the Control {@link Control#getChildren() children} list, as
+ * well as the necessary input mappings for handling key, mouse, etc events.
+ *
+ * @param control The control that this skin should be installed onto.
+ */
+ public TreeTableViewSkin(final TreeTableView<T> control) {
+ super(control);
- flow.setFixedCellSize(treeTableView.getFixedCellSize());
+ // install default input map for the TreeTableView control
+ behavior = new TreeTableViewBehavior<>(control);
+// control.setInputMap(behavior.getInputMap());
- super.init(treeTableView);
+ flow.setFixedCellSize(control.getFixedCellSize());
+ flow.setCellFactory(flow -> createCell());
setRoot(getSkinnable().getRoot());
EventHandler<MouseEvent> ml = event -> {
// RT-15127: cancel editing on scroll. This is a bit extreme
// (we are cancelling editing on touching the scrollbars).
// This can be improved at a later date.
- if (treeTableView.getEditingCell() != null) {
- treeTableView.edit(-1, null);
+ if (control.getEditingCell() != null) {
+ control.edit(-1, null);
}
// This ensures that the table maintains the focus, even when the vbar
// and hbar controls inside the flow are clicked. Without this, the
// focus border will not be shown when the user interacts with the
// scrollbars, and more importantly, keyboard navigation won't be
// available to the user.
- if (treeTableView.isFocusTraversable()) {
- treeTableView.requestFocus();
+ if (control.isFocusTraversable()) {
+ control.requestFocus();
}
};
flow.getVbar().addEventFilter(MouseEvent.MOUSE_PRESSED, ml);
flow.getHbar().addEventFilter(MouseEvent.MOUSE_PRESSED, ml);
// init the behavior 'closures'
- TreeTableViewBehavior<S> behavior = getBehavior();
- behavior.setOnFocusPreviousRow(() -> { onFocusPreviousCell(); });
- behavior.setOnFocusNextRow(() -> { onFocusNextCell(); });
- behavior.setOnMoveToFirstCell(() -> { onMoveToFirstCell(); });
- behavior.setOnMoveToLastCell(() -> { onMoveToLastCell(); });
+ behavior.setOnFocusPreviousRow(() -> onFocusPreviousCell());
+ behavior.setOnFocusNextRow(() -> onFocusNextCell());
+ behavior.setOnMoveToFirstCell(() -> onMoveToFirstCell());
+ behavior.setOnMoveToLastCell(() -> onMoveToLastCell());
behavior.setOnScrollPageDown(isFocusDriven -> onScrollPageDown(isFocusDriven));
behavior.setOnScrollPageUp(isFocusDriven -> onScrollPageUp(isFocusDriven));
- behavior.setOnSelectPreviousRow(() -> { onSelectPreviousCell(); });
- behavior.setOnSelectNextRow(() -> { onSelectNextCell(); });
- behavior.setOnSelectLeftCell(() -> { onSelectLeftCell(); });
- behavior.setOnSelectRightCell(() -> { onSelectRightCell(); });
-
- registerChangeListener(treeTableView.rootProperty(), "ROOT");
- registerChangeListener(treeTableView.showRootProperty(), "SHOW_ROOT");
- registerChangeListener(treeTableView.rowFactoryProperty(), "ROW_FACTORY");
- registerChangeListener(treeTableView.expandedItemCountProperty(), "TREE_ITEM_COUNT");
- registerChangeListener(treeTableView.fixedCellSizeProperty(), "FIXED_CELL_SIZE");
- }
+ behavior.setOnSelectPreviousRow(() -> onSelectPreviousCell());
+ behavior.setOnSelectNextRow(() -> onSelectNextCell());
+ behavior.setOnSelectLeftCell(() -> onSelectLeftCell());
+ behavior.setOnSelectRightCell(() -> onSelectRightCell());
- @Override protected void handleControlPropertyChanged(String p) {
- super.handleControlPropertyChanged(p);
-
- if ("ROOT".equals(p)) {
+ registerChangeListener(control.rootProperty(), e -> {
// fix for RT-37853
getSkinnable().edit(-1, null);
setRoot(getSkinnable().getRoot());
- } else if ("SHOW_ROOT".equals(p)) {
+ });
+ registerChangeListener(control.showRootProperty(), e -> {
// if we turn off showing the root, then we must ensure the root
// is expanded - otherwise we end up with no visible items in
// the tree.
if (! getSkinnable().isShowRoot() && getRoot() != null) {
getRoot().setExpanded(true);
}
// update the item count in the flow and behavior instances
updateRowCount();
- } else if ("ROW_FACTORY".equals(p)) {
- flow.recreateCells();
- } else if ("TREE_ITEM_COUNT".equals(p)) {
- rowCountDirty = true;
- } else if ("FIXED_CELL_SIZE".equals(p)) {
- flow.setFixedCellSize(getSkinnable().getFixedCellSize());
- }
+ });
+ registerChangeListener(control.rowFactoryProperty(), e -> flow.recreateCells());
+ registerChangeListener(control.expandedItemCountProperty(), e -> rowCountDirty = true);
+ registerChangeListener(control.fixedCellSizeProperty(), e -> flow.setFixedCellSize(getSkinnable().getFixedCellSize()));
}
+
+
/***************************************************************************
* *
- * Listeners *
+ * Public API *
* *
**************************************************************************/
+ /** {@inheritDoc} */
+ @Override public void dispose() {
+ super.dispose();
+
+ if (behavior != null) {
+ behavior.dispose();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
+ switch (attribute) {
+ case ROW_AT_INDEX: {
+ final int rowIndex = (Integer)parameters[0];
+ return rowIndex < 0 ? null : flow.getPrivateCell(rowIndex);
+ }
+ case SELECTED_ITEMS: {
+ List<Node> selection = new ArrayList<>();
+ TreeTableView.TreeTableViewSelectionModel<T> sm = getSkinnable().getSelectionModel();
+ for (TreeTablePosition<T,?> pos : sm.getSelectedCells()) {
+ TreeTableRow<T> row = flow.getPrivateCell(pos.getRow());
+ if (row != null) selection.add(row);
+ }
+ return FXCollections.observableArrayList(selection);
+ }
+ case FOCUS_ITEM: // TableViewSkinBase
+ case CELL_AT_ROW_COLUMN: // TableViewSkinBase
+ case COLUMN_AT_INDEX: // TableViewSkinBase
+ case HEADER: // TableViewSkinBase
+ case VERTICAL_SCROLLBAR: // TableViewSkinBase
+ case HORIZONTAL_SCROLLBAR: // TableViewSkinBase
+ default: return super.queryAccessibleAttribute(attribute, parameters);
+ }
+ }
+
+ @Override
+ protected void executeAccessibleAction(AccessibleAction action, Object... parameters) {
+ switch (action) {
+ case SHOW_ITEM: {
+ Node item = (Node)parameters[0];
+ if (item instanceof TreeTableCell) {
+ @SuppressWarnings("unchecked")
+ TreeTableCell<T, ?> cell = (TreeTableCell<T, ?>)item;
+ flow.scrollTo(cell.getIndex());
+ }
+ break;
+ }
+ case SET_SELECTED_ITEMS: {
+ @SuppressWarnings("unchecked")
+ ObservableList<Node> items = (ObservableList<Node>)parameters[0];
+ if (items != null) {
+ TreeTableView.TreeTableViewSelectionModel<T> sm = getSkinnable().getSelectionModel();
+ if (sm != null) {
+ sm.clearSelection();
+ for (Node item : items) {
+ if (item instanceof TreeTableCell) {
+ @SuppressWarnings("unchecked")
+ TreeTableCell<T, ?> cell = (TreeTableCell<T, ?>)item;
+ sm.select(cell.getIndex(), cell.getTableColumn());
+ }
+ }
+ }
+ }
+ break;
+ }
+ default: super.executeAccessibleAction(action, parameters);
+ }
+ }
+
/***************************************************************************
* *
- * Internal Fields *
+ * Private methods *
* *
**************************************************************************/
- private TreeTableViewBackingList<S> tableBackingList;
- private ObjectProperty<ObservableList<TreeItem<S>>> tableBackingListProperty;
- private TreeTableView<S> treeTableView;
- private WeakReference<TreeItem<S>> weakRootRef;
+ /** {@inheritDoc} */
+ private TreeTableRow<T> createCell() {
+ TreeTableRow<T> cell;
- private EventHandler<TreeItem.TreeModificationEvent<S>> rootListener = e -> {
- if (e.wasAdded() && e.wasRemoved() && e.getAddedSize() == e.getRemovedSize()) {
- // Fix for RT-14842, where the children of a TreeItem were changing,
- // but because the overall item count was staying the same, there was
- // no event being fired to the skin to be informed that the items
- // had changed. So, here we just watch for the case where the number
- // of items being added is equal to the number of items being removed.
- rowCountDirty = true;
- getSkinnable().requestLayout();
- } else if (e.getEventType().equals(TreeItem.valueChangedEvent())) {
- // Fix for RT-14971 and RT-15338.
- needCellsRebuilt = true;
- getSkinnable().requestLayout();
+ TreeTableView<T> treeTableView = getSkinnable();
+ if (treeTableView.getRowFactory() != null) {
+ cell = treeTableView.getRowFactory().call(treeTableView);
} else {
- // Fix for RT-20090. We are checking to see if the event coming
- // from the TreeItem root is an event where the count has changed.
- EventType<?> eventType = e.getEventType();
- while (eventType != null) {
- if (eventType.equals(TreeItem.<S>expandedItemCountChangeEvent())) {
- rowCountDirty = true;
- getSkinnable().requestLayout();
- break;
- }
- eventType = eventType.getSuperType();
- }
+ cell = new TreeTableRow<T>();
}
- // fix for RT-37853
- getSkinnable().edit(-1, null);
- };
+ // If there is no disclosure node, then add one of my own
+ if (cell.getDisclosureNode() == null) {
+ final StackPane disclosureNode = new StackPane();
+ disclosureNode.getStyleClass().setAll("tree-disclosure-node");
+ disclosureNode.setMouseTransparent(true);
- private WeakEventHandler<TreeModificationEvent<S>> weakRootListener;
+ final StackPane disclosureNodeArrow = new StackPane();
+ disclosureNodeArrow.getStyleClass().setAll("arrow");
+ disclosureNode.getChildren().add(disclosureNodeArrow);
+ cell.setDisclosureNode(disclosureNode);
+ }
-// private WeakReference<TreeItem> weakRoot;
- private TreeItem<S> getRoot() {
+ cell.updateTreeTableView(treeTableView);
+ return cell;
+ }
+
+ private TreeItem<T> getRoot() {
return weakRootRef == null ? null : weakRootRef.get();
}
- private void setRoot(TreeItem<S> newRoot) {
+ private void setRoot(TreeItem<T> newRoot) {
if (getRoot() != null && weakRootListener != null) {
- getRoot().removeEventHandler(TreeItem.<S>treeNotificationEvent(), weakRootListener);
+ getRoot().removeEventHandler(TreeItem.<T>treeNotificationEvent(), weakRootListener);
}
weakRootRef = new WeakReference<>(newRoot);
if (getRoot() != null) {
weakRootListener = new WeakEventHandler<>(rootListener);
- getRoot().addEventHandler(TreeItem.<S>treeNotificationEvent(), weakRootListener);
+ getRoot().addEventHandler(TreeItem.<T>treeNotificationEvent(), weakRootListener);
}
updateRowCount();
}
-
- /***************************************************************************
- * *
- * Public API *
- * *
- **************************************************************************/
-
/** {@inheritDoc} */
- @Override protected ObservableList<TreeTableColumn<S, ?>> getVisibleLeafColumns() {
- return treeTableView.getVisibleLeafColumns();
+ @Override ObservableList<TreeTableColumn<T, ?>> getVisibleLeafColumns() {
+ return getSkinnable().getVisibleLeafColumns();
}
- @Override protected int getVisibleLeafIndex(TreeTableColumn<S,?> tc) {
- return treeTableView.getVisibleLeafIndex(tc);
+ @Override int getVisibleLeafIndex(TreeTableColumn<T,?> tc) {
+ return getSkinnable().getVisibleLeafIndex(tc);
}
- @Override protected TreeTableColumn<S,?> getVisibleLeafColumn(int col) {
- return treeTableView.getVisibleLeafColumn(col);
+ @Override TreeTableColumn<T,?> getVisibleLeafColumn(int col) {
+ return getSkinnable().getVisibleLeafColumn(col);
}
/** {@inheritDoc} */
- @Override protected TreeTableView.TreeTableViewFocusModel<S> getFocusModel() {
- return treeTableView.getFocusModel();
+ @Override TreeTableView.TreeTableViewFocusModel<T> getFocusModel() {
+ return getSkinnable().getFocusModel();
}
/** {@inheritDoc} */
- @Override protected TreeTablePosition<S, ?> getFocusedCell() {
- return treeTableView.getFocusModel().getFocusedCell();
+ @Override TreeTablePosition<T, ?> getFocusedCell() {
+ return getSkinnable().getFocusModel().getFocusedCell();
}
/** {@inheritDoc} */
- @Override protected TableSelectionModel<TreeItem<S>> getSelectionModel() {
- return treeTableView.getSelectionModel();
+ @Override TableSelectionModel<TreeItem<T>> getSelectionModel() {
+ return getSkinnable().getSelectionModel();
}
/** {@inheritDoc} */
- @Override protected ObjectProperty<Callback<TreeTableView<S>, TreeTableRow<S>>> rowFactoryProperty() {
- return treeTableView.rowFactoryProperty();
+ @Override ObjectProperty<Callback<TreeTableView<T>, TreeTableRow<T>>> rowFactoryProperty() {
+ return getSkinnable().rowFactoryProperty();
}
/** {@inheritDoc} */
- @Override protected ObjectProperty<Node> placeholderProperty() {
- return treeTableView.placeholderProperty();
+ @Override ObjectProperty<Node> placeholderProperty() {
+ return getSkinnable().placeholderProperty();
}
/** {@inheritDoc} */
- @Override protected ObjectProperty<ObservableList<TreeItem<S>>> itemsProperty() {
+ @Override ObjectProperty<ObservableList<TreeItem<T>>> itemsProperty() {
+ if (tableBackingListProperty == null) {
+ this.tableBackingList = new TreeTableViewBackingList<>(getSkinnable());
+ this.tableBackingListProperty = new SimpleObjectProperty<>(tableBackingList);
+ }
return tableBackingListProperty;
}
/** {@inheritDoc} */
- @Override protected ObservableList<TreeTableColumn<S,?>> getColumns() {
- return treeTableView.getColumns();
+ @Override ObservableList<TreeTableColumn<T,?>> getColumns() {
+ return getSkinnable().getColumns();
}
/** {@inheritDoc} */
- @Override protected BooleanProperty tableMenuButtonVisibleProperty() {
- return treeTableView.tableMenuButtonVisibleProperty();
+ @Override BooleanProperty tableMenuButtonVisibleProperty() {
+ return getSkinnable().tableMenuButtonVisibleProperty();
}
/** {@inheritDoc} */
- @Override protected ObjectProperty<Callback<ResizeFeaturesBase, Boolean>> columnResizePolicyProperty() {
- // TODO Ugly!
- return (ObjectProperty<Callback<ResizeFeaturesBase, Boolean>>) (Object) treeTableView.columnResizePolicyProperty();
+ @Override ObjectProperty<Callback<ResizeFeaturesBase, Boolean>> columnResizePolicyProperty() {
+ return (ObjectProperty<Callback<ResizeFeaturesBase, Boolean>>) (Object) getSkinnable().columnResizePolicyProperty();
}
/** {@inheritDoc} */
- @Override protected ObservableList<TreeTableColumn<S,?>> getSortOrder() {
- return treeTableView.getSortOrder();
- }
-
- @Override protected boolean resizeColumn(TreeTableColumn<S,?> tc, double delta) {
- return treeTableView.resizeColumn(tc, delta);
+ @Override ObservableList<TreeTableColumn<T,?>> getSortOrder() {
+ return getSkinnable().getSortOrder();
}
- @Override protected void edit(int index, TreeTableColumn<S, ?> column) {
- treeTableView.edit(index, column);
+ @Override boolean resizeColumn(TreeTableColumn<T,?> tc, double delta) {
+ return getSkinnable().resizeColumn(tc, delta);
}
/*
* FIXME: Naive implementation ahead
* Attempts to resize column based on the pref width of all items contained
* in this column. This can be potentially very expensive if the number of
* rows is large.
*/
- @Override protected void resizeColumnToFitContent(TreeTableColumn<S,?> tc, int maxRows) {
+ @Override void resizeColumnToFitContent(TreeTableColumn<T,?> tc, int maxRows) {
final TreeTableColumn col = tc;
List<?> items = itemsProperty().get();
if (items == null || items.isEmpty()) return;
Callback cellFactory = col.getCellFactory();
if (cellFactory == null) return;
- TreeTableCell<S,?> cell = (TreeTableCell) cellFactory.call(col);
+ TreeTableCell<T,?> cell = (TreeTableCell) cellFactory.call(col);
if (cell == null) return;
// set this property to tell the TableCell we want to know its actual
// preferred width, not the width of the associated TableColumnBase
- cell.getProperties().put(TableCellSkin.DEFER_TO_PARENT_PREF_WIDTH, Boolean.TRUE);
+ cell.getProperties().put(Properties.DEFER_TO_PARENT_PREF_WIDTH, Boolean.TRUE);
// determine cell padding
double padding = 10;
Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
if (n instanceof Region) {
Region r = (Region) n;
padding = r.snappedLeftInset() + r.snappedRightInset();
}
- TreeTableRow<S> treeTableRow = new TreeTableRow<>();
+ final TreeTableView<T> treeTableView = getSkinnable();
+
+ TreeTableRow<T> treeTableRow = new TreeTableRow<>();
treeTableRow.updateTreeTableView(treeTableView);
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
double maxWidth = 0;
for (int row = 0; row < rows; row++) {
@@ -357,124 +472,24 @@
col.impl_setWidth(maxWidth);
}
/** {@inheritDoc} */
- @Override public int getItemCount() {
- return treeTableView.getExpandedItemCount();
+ @Override int getItemCount() {
+ return getSkinnable().getExpandedItemCount();
}
/** {@inheritDoc} */
- @Override public TreeTableRow<S> createCell() {
- TreeTableRow<S> cell;
-
- if (treeTableView.getRowFactory() != null) {
- cell = treeTableView.getRowFactory().call(treeTableView);
- } else {
- cell = new TreeTableRow<S>();
- }
-
- // If there is no disclosure node, then add one of my own
- if (cell.getDisclosureNode() == null) {
- final StackPane disclosureNode = new StackPane();
- disclosureNode.getStyleClass().setAll("tree-disclosure-node");
- disclosureNode.setMouseTransparent(true);
-
- final StackPane disclosureNodeArrow = new StackPane();
- disclosureNodeArrow.getStyleClass().setAll("arrow");
- disclosureNode.getChildren().add(disclosureNodeArrow);
-
- cell.setDisclosureNode(disclosureNode);
- }
-
- cell.updateTreeTableView(treeTableView);
- return cell;
- }
-
- @Override protected void horizontalScroll() {
+ @Override void horizontalScroll() {
super.horizontalScroll();
if (getSkinnable().getFixedCellSize() > 0) {
flow.requestCellLayout();
}
}
- @Override
- protected Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
- switch (attribute) {
- case ROW_AT_INDEX: {
- final int rowIndex = (Integer)parameters[0];
- return rowIndex < 0 ? null : flow.getPrivateCell(rowIndex);
- }
- case SELECTED_ITEMS: {
- List<Node> selection = new ArrayList<>();
- TreeTableView.TreeTableViewSelectionModel<S> sm = getSkinnable().getSelectionModel();
- for (TreeTablePosition<S,?> pos : sm.getSelectedCells()) {
- TreeTableRow<S> row = flow.getPrivateCell(pos.getRow());
- if (row != null) selection.add(row);
- }
- return FXCollections.observableArrayList(selection);
- }
- case FOCUS_ITEM: // TableViewSkinBase
- case CELL_AT_ROW_COLUMN: // TableViewSkinBase
- case COLUMN_AT_INDEX: // TableViewSkinBase
- case HEADER: // TableViewSkinBase
- case VERTICAL_SCROLLBAR: // TableViewSkinBase
- case HORIZONTAL_SCROLLBAR: // TableViewSkinBase
- default: return super.queryAccessibleAttribute(attribute, parameters);
- }
- }
-
- @Override
- protected void executeAccessibleAction(AccessibleAction action, Object... parameters) {
- switch (action) {
- case SHOW_ITEM: {
- Node item = (Node)parameters[0];
- if (item instanceof TreeTableCell) {
- @SuppressWarnings("unchecked")
- TreeTableCell<S, ?> cell = (TreeTableCell<S, ?>)item;
- flow.show(cell.getIndex());
- }
- break;
- }
- case SET_SELECTED_ITEMS: {
- @SuppressWarnings("unchecked")
- ObservableList<Node> items = (ObservableList<Node>)parameters[0];
- if (items != null) {
- TreeTableView.TreeTableViewSelectionModel<S> sm = getSkinnable().getSelectionModel();
- if (sm != null) {
- sm.clearSelection();
- for (Node item : items) {
- if (item instanceof TreeTableCell) {
- @SuppressWarnings("unchecked")
- TreeTableCell<S, ?> cell = (TreeTableCell<S, ?>)item;
- sm.select(cell.getIndex(), cell.getTableColumn());
- }
- }
- }
- }
- break;
- }
- default: super.executeAccessibleAction(action, parameters);
- }
- }
-
- /***************************************************************************
- * *
- * Layout *
- * *
- **************************************************************************/
-
-
-
-
- /***************************************************************************
- * *
- * Private methods *
- * *
- **************************************************************************/
-
- @Override protected void updateRowCount() {
+ /** {@inheritDoc} */
+ @Override void updateRowCount() {
updatePlaceholderRegionVisibility();
tableBackingList.resetSize();
int oldCount = flow.getCellCount();
@@ -493,33 +508,41 @@
} else {
needCellsReconfigured = true;
}
}
+
+
+ /***************************************************************************
+ * *
+ * Support classes *
+ * *
+ **************************************************************************/
+
/**
* A simple read only list structure that maps into the TreeTableView tree
* structure.
*/
- private static class TreeTableViewBackingList<S> extends ReadOnlyUnbackedObservableList<TreeItem<S>> {
- private final TreeTableView<S> treeTable;
+ private static class TreeTableViewBackingList<T> extends ReadOnlyUnbackedObservableList<TreeItem<T>> {
+ private final TreeTableView<T> treeTable;
private int size = -1;
- TreeTableViewBackingList(TreeTableView<S> treeTable) {
+ TreeTableViewBackingList(TreeTableView<T> treeTable) {
this.treeTable = treeTable;
}
void resetSize() {
int oldSize = size;
size = -1;
// TODO we can certainly make this better....but it may not really matter
- callObservers(new NonIterableChange.GenericAddRemoveChange<TreeItem<S>>(
- 0, oldSize, FXCollections.<TreeItem<S>>emptyObservableList(), this));
+ callObservers(new NonIterableChange.GenericAddRemoveChange<TreeItem<T>>(
+ 0, oldSize, FXCollections.<TreeItem<T>>emptyObservableList(), this));
}
- @Override public TreeItem<S> get(int i) {
+ @Override public TreeItem<T> get(int i) {
return treeTable.getTreeItem(i);
}
@Override public int size() {
if (size == -1) {