changeset 10068:c51351cf0902 jdk-9+139

8166021: NestedTableColumnHeader: package private access to skin prevents custom headers Reviewed-by: vadim
author jgiles
date Mon, 03 Oct 2016 09:39:29 +1300
parents ae48d430e52c
children 2eea327f6ffc 78ac39bb9b77
files modules/javafx.controls/src/main/java/javafx/scene/control/skin/NestedTableColumnHeader.java modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableColumnHeader.java modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableHeaderRow.java
diffstat 3 files changed, 65 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/NestedTableColumnHeader.java	Fri Sep 30 15:55:30 2016 -0700
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/NestedTableColumnHeader.java	Mon Oct 03 09:39:29 2016 +1300
@@ -114,11 +114,10 @@
      * Creates a new NestedTableColumnHeader instance to visually represent the given
      * {@link TableColumnBase} instance.
      *
-     * @param skin The skin used by the UI control.
      * @param tc The table column to be visually represented by this instance.
      */
-    public NestedTableColumnHeader(final TableViewSkinBase skin, final TableColumnBase tc) {
-        super(skin, tc);
+    public NestedTableColumnHeader(final TableColumnBase tc) {
+        super(tc);
 
         setFocusTraversable(false);
 
@@ -132,8 +131,6 @@
             changeListenerHandler.registerChangeListener(getTableColumn().textProperty(), e ->
                     label.setVisible(getTableColumn().getText() != null && ! getTableColumn().getText().isEmpty()));
         }
-
-        changeListenerHandler.registerChangeListener(TableSkinUtils.columnResizePolicyProperty(skin), e -> updateContent());
     }
 
 
@@ -168,7 +165,7 @@
         if (me.getClickCount() == 2 && me.isPrimaryButtonDown()) {
             // the user wants to resize the column such that its
             // width is equal to the widest element in the column
-            TableSkinUtils.resizeColumnToFitContent(header.getTableViewSkin(), column, -1);
+            TableSkinUtils.resizeColumnToFitContent(header.getTableSkin(), column, -1);
         } else {
             // rather than refer to the rect variable, we just grab
             // it from the source to prevent a small memory leak.
@@ -375,8 +372,8 @@
      */
     protected TableColumnHeader createTableColumnHeader(TableColumnBase col) {
         return col == null || col.getColumns().isEmpty() || col == getTableColumn() ?
-                new TableColumnHeader(getTableViewSkin(), col) :
-                new NestedTableColumnHeader(getTableViewSkin(), col);
+                new TableColumnHeader(col) :
+                new NestedTableColumnHeader(col);
     }
 
 
@@ -395,6 +392,11 @@
     @Override void setTableHeaderRow(TableHeaderRow header) {
         super.setTableHeaderRow(header);
 
+        // it's only now that a skin might be available
+        if (getTableSkin() != null) {
+            changeListenerHandler.registerChangeListener(TableSkinUtils.columnResizePolicyProperty(getTableSkin()), e -> updateContent());
+        }
+
         label.setTableHeaderRow(header);
 
         // tell all children columns what TableHeader they belong to
@@ -426,8 +428,8 @@
 
     void updateTableColumnHeaders() {
         // watching for changes to the view columns in either table or tableColumn.
-        if (getTableColumn() == null && getTableViewSkin() != null) {
-            setColumns(TableSkinUtils.getColumns(getTableViewSkin()));
+        if (getTableColumn() == null && getTableSkin() != null) {
+            setColumns(TableSkinUtils.getColumns(getTableSkin()));
         } else if (getTableColumn() != null) {
             setColumns(getTableColumn().getColumns());
         }
@@ -584,20 +586,19 @@
             return;
         }
 
-        final TableViewSkinBase<?,?,?,?,?> skin = getTableViewSkin();
-
         boolean isConstrainedResize = false;
-        Callback<ResizeFeaturesBase,Boolean> columnResizePolicy = TableSkinUtils.columnResizePolicyProperty(skin).get();
+        TableViewSkinBase tableSkin = getTableSkin();
+        Callback<ResizeFeaturesBase,Boolean> columnResizePolicy = TableSkinUtils.columnResizePolicyProperty(tableSkin).get();
         if (columnResizePolicy != null) {
             isConstrainedResize =
-                    skin instanceof TableViewSkin ? TableView.CONSTRAINED_RESIZE_POLICY.equals(columnResizePolicy) :
-                    skin instanceof TreeTableViewSkin ? TreeTableView.CONSTRAINED_RESIZE_POLICY.equals(columnResizePolicy) :
+                    tableSkin instanceof TableViewSkin ? TableView.CONSTRAINED_RESIZE_POLICY.equals(columnResizePolicy) :
+                    tableSkin instanceof TreeTableViewSkin ? TreeTableView.CONSTRAINED_RESIZE_POLICY.equals(columnResizePolicy) :
                     false;
         }
 
         // RT-32547 - don't show resize cursor when in constrained resize mode
         // and there is only one column
-        if (isConstrainedResize && TableSkinUtils.getVisibleLeafColumns(skin).size() == 1) {
+        if (isConstrainedResize && TableSkinUtils.getVisibleLeafColumns(tableSkin).size() == 1) {
             return;
         }
 
@@ -664,7 +665,7 @@
             draggedX = -draggedX;
         }
         double delta = draggedX - lastX;
-        boolean allowed = TableSkinUtils.resizeColumn(getTableViewSkin(), col, delta);
+        boolean allowed = TableSkinUtils.resizeColumn(getTableSkin(), col, delta);
         if (allowed) {
             lastX = draggedX;
         }
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableColumnHeader.java	Fri Sep 30 15:55:30 2016 -0700
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableColumnHeader.java	Mon Oct 03 09:39:29 2016 +1300
@@ -74,7 +74,8 @@
 
 
 /**
- * Region responsible for painting a single column header.
+ * Region responsible for painting a single column header. A subcomponent used by
+ * subclasses of {@link TableViewSkinBase}.
  *
  * @since 9
  */
@@ -103,7 +104,6 @@
     private boolean autoSizeComplete = false;
 
     private double dragOffset;
-    private final TableViewSkinBase<?,?,?,?,TableColumnBase<?,?>> skin;
     private NestedTableColumnHeader nestedColumnHeader;
     private TableHeaderRow tableHeaderRow;
     private NestedTableColumnHeader parentHeader;
@@ -131,7 +131,7 @@
     // the line drawn in the table when a user presses and moves a column header
     // to indicate where the column will be dropped. This is provided by the
     // table skin, but manipulated by the header
-    final Region columnReorderLine;
+    Region columnReorderLine;
 
 
 
@@ -145,17 +145,12 @@
      * Creates a new TableColumnHeader instance to visually represent the given
      * {@link TableColumnBase} instance.
      *
-     * @param skin The skin used by the UI control.
      * @param tc The table column to be visually represented by this instance.
      */
-    public TableColumnHeader(final TableViewSkinBase skin, final TableColumnBase tc) {
-        this.skin = skin;
+    public TableColumnHeader(final TableColumnBase tc) {
         setTableColumn(tc);
-        this.columnReorderLine = skin.getColumnReorderLine();
-
         setFocusTraversable(false);
 
-        updateColumnIndex();
         initStyleClasses();
         initUI();
 
@@ -164,12 +159,6 @@
         changeListenerHandler.registerChangeListener(sceneProperty(), e -> updateScene());
 
         if (getTableColumn() != null) {
-            updateSortPosition();
-            TableSkinUtils.getSortOrder(skin).addListener(weakSortOrderListener);
-            TableSkinUtils.getVisibleLeafColumns(skin).addListener(weakVisibleLeafColumnsListener);
-        }
-
-        if (getTableColumn() != null) {
             changeListenerHandler.registerChangeListener(tc.idProperty(), e -> setId(tc.getId()));
             changeListenerHandler.registerChangeListener(tc.styleProperty(), e -> setStyle(tc.getStyle()));
             changeListenerHandler.registerChangeListener(tc.widthProperty(), e -> {
@@ -183,7 +172,7 @@
             changeListenerHandler.registerChangeListener(tc.sortableProperty(), e -> {
                 // we need to notify all headers that a sortable state has changed,
                 // in case the sort grid in other columns needs to be updated.
-                if (TableSkinUtils.getSortOrder(skin).contains(getTableColumn())) {
+                if (TableSkinUtils.getSortOrder(getTableSkin()).contains(getTableColumn())) {
                     NestedTableColumnHeader root = getTableHeaderRow().getRootHeader();
                     updateAllHeaders(root);
                 }
@@ -251,7 +240,7 @@
 
         // pass focus to the table, so that the user immediately sees
         // the focus rectangle around the table control.
-        header.getTableViewSkin().getSkinnable().requestFocus();
+        header.getTableSkin().getSkinnable().requestFocus();
 
         if (me.isPrimaryButtonDown() && header.isColumnReorderingEnabled()) {
             header.columnReorderingStarted(me.getX());
@@ -463,15 +452,34 @@
         }
     }
 
-    TableViewSkinBase<?,?,?,?,TableColumnBase<?,?>> getTableViewSkin() {
-        return skin;
-    }
-
     NestedTableColumnHeader getNestedColumnHeader() { return nestedColumnHeader; }
     void setNestedColumnHeader(NestedTableColumnHeader nch) { nestedColumnHeader = nch; }
 
     TableHeaderRow getTableHeaderRow() { return tableHeaderRow; }
-    void setTableHeaderRow(TableHeaderRow thr) { tableHeaderRow = thr; }
+    void setTableHeaderRow(TableHeaderRow thr) {
+        tableHeaderRow = thr;
+        updateTableSkin();
+    }
+
+    private void updateTableSkin() {
+        // when we get the table header row, we are also given the skin,
+        // so this is the time to hook up listeners, etc.
+        TableViewSkinBase<?,?,?,?,?> tableSkin = getTableSkin();
+        if (tableSkin == null) return;
+
+        updateColumnIndex();
+        this.columnReorderLine = tableSkin.getColumnReorderLine();
+
+        if (getTableColumn() != null) {
+            updateSortPosition();
+            TableSkinUtils.getSortOrder(tableSkin).addListener(weakSortOrderListener);
+            TableSkinUtils.getVisibleLeafColumns(tableSkin).addListener(weakVisibleLeafColumnsListener);
+        }
+    }
+
+    TableViewSkinBase<?,?,?,?,?> getTableSkin() {
+        return tableHeaderRow == null ? null : tableHeaderRow.tableSkin;
+    }
 
     NestedTableColumnHeader getParentHeader() { return parentHeader; }
     void setParentHeader(NestedTableColumnHeader ph) { parentHeader = ph; }
@@ -511,10 +519,10 @@
     }
 
     void dispose() {
-        TableViewSkinBase skin = getTableViewSkin();
-        if (skin != null) {
-            TableSkinUtils.getVisibleLeafColumns(skin).removeListener(weakVisibleLeafColumnsListener);
-            TableSkinUtils.getSortOrder(skin).removeListener(weakSortOrderListener);
+        TableViewSkinBase tableSkin = getTableSkin();
+        if (tableSkin != null) {
+            TableSkinUtils.getVisibleLeafColumns(tableSkin).removeListener(weakVisibleLeafColumnsListener);
+            TableSkinUtils.getSortOrder(tableSkin).removeListener(weakSortOrderListener);
         }
 
         changeListenerHandler.dispose();
@@ -529,7 +537,7 @@
 
     private boolean isColumnReorderingEnabled() {
         // we only allow for column reordering if there are more than one column,
-        return !Properties.IS_TOUCH_SUPPORTED && TableSkinUtils.getVisibleLeafColumns(getTableViewSkin()).size() > 1;
+        return !Properties.IS_TOUCH_SUPPORTED && TableSkinUtils.getVisibleLeafColumns(getTableSkin()).size() > 1;
     }
 
     private void initUI() {
@@ -562,7 +570,7 @@
 
         // if the prefWidth has been set, we do _not_ autosize columns
         if (prefWidth == DEFAULT_COLUMN_WIDTH) {
-            TableSkinUtils.resizeColumnToFitContent(getTableViewSkin(), column, cellsToMeasure);
+            TableSkinUtils.resizeColumnToFitContent(getTableSkin(), column, cellsToMeasure);
 //            getTableViewSkin().resizeColumnToFitContent(column, cellsToMeasure);
         }
     }
@@ -591,7 +599,7 @@
         }
 
         // RT-28016: if the tablecolumn is not a visible leaf column, we should ignore this
-        int visibleLeafIndex = TableSkinUtils.getVisibleLeafIndex(skin,getTableColumn());
+        int visibleLeafIndex = TableSkinUtils.getVisibleLeafIndex(getTableSkin(), getTableColumn());
         if (visibleLeafIndex == -1) return;
 
         final int sortColumnCount = getVisibleSortOrderColumnCount();
@@ -747,7 +755,7 @@
 
     private ObservableList<TableColumnBase<?,?>> getColumns(TableColumnBase column) {
         return column.getParentColumn() == null ?
-                TableSkinUtils.getColumns(getTableViewSkin()) :
+                TableSkinUtils.getColumns(getTableSkin()) :
                 column.getParentColumn().getColumns();
     }
 
@@ -770,15 +778,15 @@
 
     private void updateColumnIndex() {
 //        TableView tv = getTableView();
-        TableViewSkinBase skin = getTableViewSkin();
         TableColumnBase tc = getTableColumn();
-        columnIndex = skin == null || tc == null ? -1 :TableSkinUtils.getVisibleLeafIndex(skin,tc);
+        TableViewSkinBase tableSkin = getTableSkin();
+        columnIndex = tableSkin == null || tc == null ? -1 :TableSkinUtils.getVisibleLeafIndex(tableSkin,tc);
 
         // update the pseudo class state regarding whether this is the last
         // visible cell (i.e. the right-most).
         isLastVisibleColumn = getTableColumn() != null &&
                 columnIndex != -1 &&
-                columnIndex == TableSkinUtils.getVisibleLeafColumns(skin).size() - 1;
+                columnIndex == TableSkinUtils.getVisibleLeafColumns(tableSkin).size() - 1;
         pseudoClassStateChanged(PSEUDO_CLASS_LAST_VISIBLE, isLastVisibleColumn);
     }
 
@@ -791,7 +799,7 @@
 //        final int sortPos = getTable().getSortOrder().indexOf(column);
 //        final boolean isSortColumn = sortPos != -1;
 
-        final ObservableList<TableColumnBase<?,?>> sortOrder = TableSkinUtils.getSortOrder(skin);
+        final ObservableList<TableColumnBase<?,?>> sortOrder = TableSkinUtils.getSortOrder(getTableSkin());
 
         // addColumn is true e.g. when the user is holding down Shift
         if (addColumn) {
@@ -871,7 +879,7 @@
     }
 
     private List<TableColumnBase> getVisibleSortOrderColumns() {
-        final ObservableList<TableColumnBase<?,?>> sortOrder = TableSkinUtils.getSortOrder(skin);
+        final ObservableList<TableColumnBase<?,?>> sortOrder = TableSkinUtils.getSortOrder(getTableSkin());
 
         List<TableColumnBase> visibleSortOrderColumns = new ArrayList<>();
         for (int i = 0; i < sortOrder.size(); i++) {
@@ -934,7 +942,7 @@
         final double x = getParentHeader().sceneToLocal(sceneX, sceneY).getX();
 
         // calculate where the ghost column header should be
-        double dragX = getTableViewSkin().getSkinnable().sceneToLocal(sceneX, sceneY).getX() - dragOffset;
+        double dragX = getTableSkin().getSkinnable().sceneToLocal(sceneX, sceneY).getX() - dragOffset;
         getTableHeaderRow().setDragHeaderX(dragX);
 
         double startX = 0;
@@ -982,7 +990,7 @@
         double lineX = getTableHeaderRow().sceneToLocal(hoverHeader.localToScene(hoverHeader.getBoundsInLocal())).getMinX();
         lineX = lineX + ((beforeMidPoint) ? (0) : (hoverHeader.getWidth()));
 
-        if (lineX >= -0.5 && lineX <= getTableViewSkin().getSkinnable().getWidth()) {
+        if (lineX >= -0.5 && lineX <= getTableSkin().getSkinnable().getWidth()) {
             columnReorderLine.setTranslateX(lineX);
 
             // then if this is the first event, we set the property to true
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableHeaderRow.java	Fri Sep 30 15:55:30 2016 -0700
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableHeaderRow.java	Mon Oct 03 09:39:29 2016 +1300
@@ -85,7 +85,7 @@
             ControlResources.getString("TableView.nestedColumnControlMenuSeparator");
 
     private final VirtualFlow flow;
-    private final TableViewSkinBase<?,?,?,?,?> tableSkin;
+    final TableViewSkinBase<?,?,?,?,?> tableSkin;
     private Map<TableColumnBase, CheckMenuItem> columnMenuItems = new HashMap<TableColumnBase, CheckMenuItem>();
     private double scrollX;
     private double tableWidth;
@@ -413,7 +413,7 @@
      * @return A new NestedTableColumnHeader instance.
      */
     protected NestedTableColumnHeader createRootHeader() {
-        return new NestedTableColumnHeader(tableSkin, null);
+        return new NestedTableColumnHeader(null);
     }