changeset 2128:955b583b0ce5

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/8.0/scrum/controls/jfx/rt
author jgiles
date Fri, 04 Jan 2013 11:51:34 +1300
parents c80842bf169a 39aa29468f43
children 02985c07385e faf337dd0958
files javafx-ui-controls/src/javafx/scene/control/TreeTableView.java
diffstat 11 files changed, 224 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableCellSkinBase.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableCellSkinBase.java	Fri Jan 04 11:51:34 2013 +1300
@@ -46,7 +46,7 @@
     // clicks result in the column being resized to fit the widest content in 
     // the column
     static final String DEFER_TO_PARENT_PREF_WIDTH = "deferToParentPrefWidth";
-    private boolean isDeferToParentForPrefWidth = false;
+    boolean isDeferToParentForPrefWidth = false;
     
     private InvalidationListener columnWidthListener = new InvalidationListener() {
         @Override public void invalidated(Observable valueModel) {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkinBase.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableRowSkinBase.java	Fri Jan 04 11:51:34 2013 +1300
@@ -83,6 +83,10 @@
     protected boolean isIndentationRequired() {
         return false;
     }
+    
+    protected TableColumnBase getTreeColumn() {
+        return null;
+    }
 
     protected Node getDisclosureNode() {
         return null;
@@ -163,14 +167,9 @@
     
     private int fullRefreshCounter = DEFAULT_FULL_REFRESH_COUNTER;
 
-//    protected boolean showColumns = true;
-    
     protected boolean isDirty = false;
     protected boolean updateCells = false;
     
-//    private TableView<T> tableView;
-//    private TableViewSkin tableViewSkin;
-    
     private final double fixedCellLength;
     private final boolean fixedCellLengthEnabled;
     
@@ -182,9 +181,7 @@
     };
     
     // spanning support
-//    private CellSpanTableView<T> cellSpanTableView;
     protected SpanModel spanModel;
-//    private static final Map<TableView, SpanType[][]> spanMap = new WeakHashMap<TableView, SpanType[][]>();
     
     // supports variable row heights
     public static <C extends IndexedCell> double getTableRowHeight(int index, C tableRow) {
@@ -368,19 +365,6 @@
         }
     }
 
-//    private void updateShowColumns() {
-//        boolean newValue = (isIgnoreText() && isIgnoreGraphic());
-//        if (showColumns == newValue) return;
-//        
-//        showColumns = newValue;
-////        showColumns = true;
-//        
-//        System.out.println("showColumns is " + showColumns + " for row " + getSkinnable().getIndex());
-//
-//        updateCells = true;
-//        requestLayout();
-//    }
-    
     @Override protected void layoutChildren(double x, final double y,
             double w, final double h) {
         
@@ -395,7 +379,9 @@
         
         if (cellsMap.isEmpty()) return;
         
-        if (/*showColumns && */! getVisibleLeafColumns().isEmpty()) {
+        
+        ObservableList<? extends TableColumnBase> visibleLeafColumns = getVisibleLeafColumns();
+        if (! visibleLeafColumns.isEmpty()) {
             
             ///////////////////////////////////////////
             // indentation code starts here
@@ -404,14 +390,21 @@
             double disclosureWidth = 0;
             boolean indentationRequired = isIndentationRequired();
             boolean disclosureVisible = isDisclosureNodeVisible();
+            int indentationColumnIndex = 0;
+            Node disclosureNode = null;
             if (indentationRequired) {
+                // Determine the column in which we want to put the disclosure node.
+                // By default it is null, which means the 0th column should be
+                // where the indentation occurs.
+                TableColumnBase treeColumn = getTreeColumn();
+                indentationColumnIndex = treeColumn == null ? 0 : visibleLeafColumns.indexOf(treeColumn);
+                indentationColumnIndex = indentationColumnIndex < 0 ? 0 : indentationColumnIndex;
+                
                 int indentationLevel = getIndentationLevel(getSkinnable());
                 if (! isShowRoot()) indentationLevel--;
                 final double indentationPerLevel = getIndentationPerLevel();
                 leftMargin = indentationLevel * indentationPerLevel;
             
-                x += leftMargin;
-                
                 // position the disclosure node so that it is at the proper indent
                 Control c = getVirtualFlowOwner();
                 final double defaultDisclosureWidth = maxDisclosureWidthMap.containsKey(c) ?
@@ -419,25 +412,12 @@
                 disclosureWidth = defaultDisclosureWidth;
 
                 if (disclosureVisible) {
-                    Node disclosureNode = getDisclosureNode();
-                    disclosureWidth = disclosureNode.prefWidth(-1);
+                    disclosureNode = getDisclosureNode();
+                    disclosureWidth = disclosureNode.prefWidth(h);
                     if (disclosureWidth > defaultDisclosureWidth) {
                         maxDisclosureWidthMap.put(c, disclosureWidth);
                     }
-
-                    double ph = disclosureNode.prefHeight(-1);
-
-                    disclosureNode.resize(disclosureWidth, ph);
-                    positionInArea(disclosureNode, x, y,
-                            disclosureWidth, h, /*baseline ignored*/0,
-                            HPos.CENTER, VPos.CENTER);
                 }
-
-                // determine starting point of the graphic or cell node, and the
-                // remaining width available to them
-                final int padding = getGraphic() == null ? 0 : 3;
-                x += disclosureWidth + padding;
-                w -= (leftMargin + disclosureWidth + padding);
             }
             ///////////////////////////////////////////
             // indentation code ends here
@@ -451,9 +431,16 @@
             
             double verticalPadding = insets.getTop() + insets.getBottom();
             double horizontalPadding = insets.getLeft() + insets.getRight();
-            
+
+            /**
+             * RT-26743:TreeTableView: Vertical Line looks unfinished.
+             * We used to not do layout on cells whose row exceeded the number
+             * of items, but now we do so as to ensure we get vertical lines
+             * where expected in cases where the vertical height exceeds the 
+             * number of items.
+             */
             int row = getSkinnable().getIndex();
-            if (row < 0 || row >= itemsProperty().get().size()) return;
+            if (row < 0/* || row >= itemsProperty().get().size()*/) return;
             
             for (int column = 0, max = cells.size(); column < max; column++) {
                 R tableCell = cells.get(column);
@@ -487,6 +474,38 @@
                         getChildren().add(tableCell);
                     }
                     
+                    
+                    
+                    ///////////////////////////////////////////
+                    // further indentation code starts here
+                    ///////////////////////////////////////////
+                    if (indentationRequired && column == indentationColumnIndex) {
+                        x += leftMargin;
+                        
+                        if (disclosureVisible) {
+                            double ph = disclosureNode.prefHeight(disclosureWidth);
+                            
+                            if (width < (disclosureWidth + leftMargin)) {
+                                disclosureNode.setVisible(false);
+                            } else {
+                                disclosureNode.setVisible(true);
+                                disclosureNode.resize(disclosureWidth, ph);
+                                positionInArea(disclosureNode, x, y,
+                                        disclosureWidth, ph, /*baseline ignored*/0,
+                                        HPos.CENTER, VPos.CENTER);
+                            }
+                        }
+                        
+                        // determine starting point of the graphic or cell node, and the
+                        // remaining width available to them
+                        final int padding = getGraphic() == null ? 0 : 3;
+                        x += disclosureWidth + padding;
+                        w -= (leftMargin + disclosureWidth + padding);
+                    }
+                    ///////////////////////////////////////////
+                    // further indentation code ends here
+                    ///////////////////////////////////////////
+                    
                     ///////////////////////////////////////////
                     // cell spanning code starts here
                     ///////////////////////////////////////////
@@ -539,13 +558,27 @@
                     // cell spanning code ends here
                     ///////////////////////////////////////////
                     
-                    // a little bit more special code for indentation purposes
-                    if (indentationRequired && column == 0) {
-                        tableCell.resize(width - leftMargin - disclosureWidth, height);
-                        tableCell.relocate(x, insets.getTop());
+                    // a little bit more special code for indentation purposes.
+                    // we use j here to prevent the table cells being sized as
+                    // negative or 0 widths. If this is allowed, the vertical 
+                    // lines for that column are removed from view, which 
+                    // doesn't look right.
+                    double j = width - (leftMargin + disclosureWidth);
+                    if (indentationRequired && column == indentationColumnIndex) {
+                        // the min width of a table cell is now 1 pixel
+                        tableCell.resize(Math.max(1, j), height);
                     } else {
                         tableCell.resize(width, height);
+                    }
+
+                    if (indentationRequired && column > indentationColumnIndex) {
                         tableCell.relocate(x - leftMargin - disclosureWidth, insets.getTop());
+                    } else {
+                        // if j is a negative number (because the width is smaller
+                        // that the left margin and disclosure node), we relocate
+                        // the cell to the left (and subtract 1 to take into 
+                        // account the minimum 1px width we resize cells to above).
+                        tableCell.relocate(x + Math.min(0, j - 1), insets.getTop());
                     }
                 } else {
                     if (fixedCellLengthEnabled) {
@@ -629,8 +662,8 @@
                 R cell = cellsMap.get(col);
                 if (cell == null) continue;
 
+                updateCell(cell, skinnable);
                 cell.updateIndex(skinnableIndex);
-                updateCell(cell, skinnable);
                 cells.add(cell);
             }
 //        }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableViewSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TableViewSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -247,7 +247,13 @@
             }
         }
         
-        col.impl_setWidth(maxWidth + padding);
+        // RT-23486
+        double widthMax = maxWidth + padding;
+        if(tableView.getColumnResizePolicy() == TableView.CONSTRAINED_RESIZE_POLICY) {
+             widthMax = Math.max(widthMax, col.getWidth());
+        }
+
+        col.impl_setWidth(widthMax); 
     }
     
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeCellSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeCellSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -121,6 +121,9 @@
         } else if (disclosureNode.getParent() == null) {
             getChildren().add(disclosureNode);
             disclosureNode.toFront();
+            
+            // RT-26625: [TreeView, TreeTableView] can lose arrows while scrolling
+            disclosureNode.impl_processCSS(true);
         } else {
             disclosureNode.toBack();
         }
@@ -160,16 +163,16 @@
             }
             
             if (disclosureNode != null) {
-                disclosureWidth = disclosureNode.prefWidth(-1);
+                disclosureWidth = disclosureNode.prefWidth(h);
                 if (disclosureWidth > defaultDisclosureWidth) {
                     maxDisclosureWidthMap.put(tree, disclosureWidth);
                 }
 
-                double ph = disclosureNode.prefHeight(-1);
-
+                double ph = disclosureNode.prefHeight(disclosureWidth);
+                
                 disclosureNode.resize(disclosureWidth, ph);
                 positionInArea(disclosureNode, x, y,
-                        disclosureWidth, h, /*baseline ignored*/0,
+                        disclosureWidth, ph, /*baseline ignored*/0,
                         HPos.CENTER, VPos.CENTER);
             }
         }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableCellSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableCellSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -27,8 +27,12 @@
 import com.sun.javafx.scene.control.behavior.TreeTableCellBehavior;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.ReadOnlyDoubleProperty;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
 import javafx.scene.control.TreeTableCell;
 import javafx.scene.control.TreeTableColumn;
+import javafx.scene.control.TreeTableRow;
+import javafx.scene.control.TreeTableView;
 
 /**
  */
@@ -53,4 +57,39 @@
     @Override protected ReadOnlyDoubleProperty columnWidthProperty() {
         return tableColumn.widthProperty();
     }
+    
+    @Override protected double computePrefWidth(double height) {
+        if (isDeferToParentForPrefWidth) {
+            // RT-27167: we must take into account the disclosure node and the
+            // indentation (which is not taken into account by the LabeledSkinBase.
+            double ph = super.computePrefWidth(height);
+            
+            TreeTableRow treeTableRow = getSkinnable().getTreeTableRow();
+            if (treeTableRow != null) {
+                TreeItem treeItem = treeTableRow.getTreeItem();
+                if (treeItem != null) {
+                    int nodeLevel = TreeTableView.getNodeLevel(treeItem);
+                    if (!treeTableRow.getTreeTableView().isShowRoot()) nodeLevel--;
+                    
+                    // FIXME we're assuming an indent of 10px here, which is not
+                    // necessarily accurate as it is configurable via -fx-indent.
+                    // Unfortunately this value is stored in TreeTableRowSkin.
+                    ph += nodeLevel * 10;
+                    
+                    // Adding a little extra for padding
+                    ph += 10;
+
+                    // add in the width of the disclosure node, if one exists
+                    Node disclosureNode = treeTableRow.getDisclosureNode();
+                    if (disclosureNode != null) {
+                        double disclosureNodeWidth = disclosureNode.prefWidth(height);
+                        ph += disclosureNodeWidth;
+                    }
+                }
+            }
+            
+            return ph;
+        }
+        return columnWidthProperty().get();
+    }
 }
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableRowSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableRowSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -70,6 +70,7 @@
         registerChangeListener(control.indexProperty(), "INDEX");
         registerChangeListener(control.treeTableViewProperty(), "TREE_TABLE_VIEW");
         registerChangeListener(control.treeItemProperty(), "TREE_ITEM");
+        registerChangeListener(control.getTreeTableView().treeColumnProperty(), "TREE_COLUMN");
     }
     
     @Override protected void handleControlPropertyChanged(String p) {
@@ -84,6 +85,9 @@
             }
         } else if ("TREE_ITEM".equals(p)) {
             updateDisclosureNode();
+        } else if ("TREE_COLUMN".equals(p)) {
+            updateCells = true;
+            requestLayout();
         }
     }
     
@@ -131,6 +135,9 @@
         } else if (disclosureNode.getParent() == null) {
             getChildren().add(disclosureNode);
             disclosureNode.toFront();
+            
+            // RT-26625: [TreeView, TreeTableView] can lose arrows while scrolling
+            disclosureNode.impl_processCSS(true);
         } else {
             disclosureNode.toBack();
         }
@@ -176,6 +183,10 @@
     @Override protected boolean isIndentationRequired() {
         return true;
     }
+
+    @Override protected TableColumnBase getTreeColumn() {
+        return getSkinnable().getTreeTableView().getTreeColumn();
+    }
     
     @Override protected int getIndentationLevel(TreeTableRow<T> control) {
         return TreeTableView.getNodeLevel(control.getTreeItem());
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableViewSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeTableViewSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -230,6 +230,8 @@
             weakRootListener = new WeakEventHandler(rootListener);
             getRoot().addEventHandler(TreeItem.<S>treeNotificationEvent(), weakRootListener);
         }
+        
+        updateItemCount();
     }
     
     
@@ -336,22 +338,38 @@
             padding = r.getInsets().getLeft() + r.getInsets().getRight();
         } 
         
+        TreeTableRow 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++) {
+            treeTableRow.updateIndex(row);
+            treeTableRow.updateTreeItem(treeTableView.getTreeItem(row));
+            
             cell.updateTreeTableColumn(col);
             cell.updateTreeTableView(treeTableView);
+            cell.updateTreeTableRow(treeTableRow);
             cell.updateIndex(row);
             
             if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
                 getChildren().add(cell);
                 cell.impl_processCSS(false);
-                maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
+                
+                double w = cell.prefWidth(-1);
+                
+                maxWidth = Math.max(maxWidth, w);
                 getChildren().remove(cell);
             }
         }
         
-        col.impl_setWidth(maxWidth + padding);
+        // RT-23486
+        double widthMax = maxWidth + padding;
+        if(treeTableView.getColumnResizePolicy() == TreeTableView.CONSTRAINED_RESIZE_POLICY) {
+             widthMax = Math.max(widthMax, col.getWidth());
+        }
+
+        col.impl_setWidth(widthMax); 
     }
     
     /** {@inheritDoc} */
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeViewSkin.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TreeViewSkin.java	Fri Jan 04 11:51:34 2013 +1300
@@ -194,6 +194,8 @@
             weakRootListener = new WeakEventHandler(rootListener);
             getRoot().addEventHandler(TreeItem.<T>treeNotificationEvent(), weakRootListener);
         }
+        
+        updateItemCount();
     }
 
     @Override public int getItemCount() {
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/caspian.css	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/caspian.css	Fri Jan 04 11:51:34 2013 +1300
@@ -2312,9 +2312,7 @@
    TableColumn, and a 'filler' area that extends from the right-most column
    to the edge of the tableview, or up to the 'column control' button. */
 .table-view .column-header,
-.table-view .filler,
-.tree-table-view .column-header,
-.tree-table-view .filler{
+.tree-table-view .column-header {
     -fx-text-fill: -fx-selection-bar-text;
 
     /* TODO: for some reason, this doesn't scale. */
@@ -2336,6 +2334,26 @@
     -fx-border-width: 0.083333em, 0.083333em;
 }
 
+.table-view .filler,
+.tree-table-view .filler {
+    -fx-size: 25;
+    -fx-border-style: solid;
+    -fx-border-color: 
+        /* 
+          Inner border: we have different colours along the top, right, bottom and left.
+          Refer to RT-12298 for the spec.
+        */
+        derive(-fx-base, 80%) 
+        linear-gradient(to bottom, derive(-fx-base,80%) 20%, derive(-fx-base,-10%) 90%)
+        derive(-fx-base, 10%) 
+        linear-gradient(to bottom, derive(-fx-base,80%) 20%, derive(-fx-base,-10%) 90%),
+        /* Outer border: */
+        transparent transparent -fx-table-header-border-color transparent;
+    -fx-border-insets: 0 0 1 0, 0 0 0 0;
+    -fx-border-width: 0.083333em, 0.083333em 0 0.083333em 0.083333em;
+}
+
+
 .table-view .column-header .sort-order,
 .tree-table-view .column-header .sort-order{
     -fx-font-size: 0.916667em; /* 11pt - 1 less than the default font */
--- a/javafx-ui-controls/src/javafx/scene/control/TreeTableView.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/src/javafx/scene/control/TreeTableView.java	Fri Jan 04 11:51:34 2013 +1300
@@ -693,6 +693,31 @@
     }
     
     
+    
+    // --- Tree Column
+    private ObjectProperty<TreeTableColumn<S,?>> treeColumn;
+    /**
+     * Property that represents which column should have the disclosure node
+     * shown in it (that is, the column with the arrow). By default this will be
+     * the left-most column if this property is null, otherwise it will be the
+     * specified column assuming it is non-null and contained within the 
+     * {@link #getVisibleLeafColumns() visible leaf columns} list.
+     */
+    public final ObjectProperty<TreeTableColumn<S,?>> treeColumnProperty() {
+        if (treeColumn == null) {
+            treeColumn = new SimpleObjectProperty<TreeTableColumn<S,?>>(this, "treeColumn", null);
+        }
+        return treeColumn;
+    }
+    public final void setTreeColumn(TreeTableColumn<S,?> value) {
+        treeColumnProperty().set(value);
+    }
+    public final TreeTableColumn<S,?> getTreeColumn() {
+        return treeColumn == null ? null : treeColumn.get();
+    }
+    
+    
+    
     // --- Selection Model
     private ObjectProperty<TreeTableViewSelectionModel<S>> selectionModel;
 
--- a/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Wed Jan 02 10:57:04 2013 -0500
+++ b/javafx-ui-controls/test/javafx/scene/control/TreeViewTest.java	Fri Jan 04 11:51:34 2013 +1300
@@ -210,7 +210,7 @@
         assertEquals(0, treeView.getRow(root));
     }
     
-    @Test public void ensureRootIndexIsNegativeOne1WhenRootIsNotShowing() {
+    @Test public void ensureRootIndexIsNegativeOneWhenRootIsNotShowing() {
         installChildren();
         treeView.setShowRoot(false);
         assertEquals(-1, treeView.getRow(root));
@@ -241,6 +241,18 @@
         assertEquals(-1, treeView.getRow(child3));
     }
     
+    @Test public void ensureCorrectIndexWhenRootTreeItemIsCollapsed() {
+        installChildren();
+        root.setExpanded(false);
+        assertEquals(0, treeView.getRow(root));
+        
+        // note that the indices are still positive, representing what the values
+        // would be if this row is visible
+        assertEquals(1, treeView.getRow(child1));
+        assertEquals(2, treeView.getRow(child2));
+        assertEquals(3, treeView.getRow(child3));
+    }
+    
     @Test public void removingLastTest() {
         TreeView tree_view = new TreeView();
         MultipleSelectionModel sm = tree_view.getSelectionModel();