modules/controls/src/main/java/javafx/scene/control/skin/TableColumnHeader.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

*** 21,33 **** * 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; import javafx.beans.property.DoubleProperty; import javafx.beans.value.WritableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.WeakListChangeListener; import javafx.css.CssMetaData; --- 21,37 ---- * 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 javafx.scene.control.skin; + import com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler; + import com.sun.javafx.scene.control.Properties; import javafx.beans.property.DoubleProperty; + import javafx.beans.property.ReadOnlyObjectProperty; + import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.WritableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.collections.WeakListChangeListener; import javafx.css.CssMetaData;
*** 57,68 **** import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; ! import com.sun.javafx.css.converters.SizeConverter; ! import com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.getSortTypeName; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.getSortTypeProperty; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.isAscending; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.isDescending; --- 61,71 ---- import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; ! import javafx.css.converter.SizeConverter; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.getSortTypeName; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.getSortTypeProperty; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.isAscending; import static com.sun.javafx.scene.control.TableColumnSortTypeWrapper.isDescending;
*** 93,105 **** **************************************************************************/ private boolean autoSizeComplete = false; private double dragOffset; ! private final TableViewSkinBase<?,?,?,?,?,TableColumnBase<?,?>> skin; private NestedTableColumnHeader nestedColumnHeader; - private final TableColumnBase<?,?> column; private TableHeaderRow tableHeaderRow; private NestedTableColumnHeader parentHeader; // work out where this column currently is within its parent Label label; --- 96,107 ---- **************************************************************************/ private boolean autoSizeComplete = false; private double dragOffset; ! private final TableViewSkinBase<?,?,?,?,TableColumnBase<?,?>> skin; private NestedTableColumnHeader nestedColumnHeader; private TableHeaderRow tableHeaderRow; private NestedTableColumnHeader parentHeader; // work out where this column currently is within its parent Label label;
*** 122,178 **** private int newColumnPos; // 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 ! protected final Region columnReorderLine; /*************************************************************************** * * * Constructor * * * **************************************************************************/ public TableColumnHeader(final TableViewSkinBase skin, final TableColumnBase tc) { this.skin = skin; ! this.column = tc; this.columnReorderLine = skin.getColumnReorderLine(); setFocusTraversable(false); updateColumnIndex(); initUI(); // change listener for multiple properties ! changeListenerHandler = new MultiplePropertyChangeListenerHandler(p -> { ! handlePropertyChanged(p); ! return null; ! }); ! changeListenerHandler.registerChangeListener(sceneProperty(), "SCENE"); ! if (column != null && skin != null) { updateSortPosition(); skin.getSortOrder().addListener(weakSortOrderListener); skin.getVisibleLeafColumns().addListener(weakVisibleLeafColumnsListener); } ! if (column != null) { ! changeListenerHandler.registerChangeListener(column.idProperty(), "TABLE_COLUMN_ID"); ! changeListenerHandler.registerChangeListener(column.styleProperty(), "TABLE_COLUMN_STYLE"); ! changeListenerHandler.registerChangeListener(column.widthProperty(), "TABLE_COLUMN_WIDTH"); ! changeListenerHandler.registerChangeListener(column.visibleProperty(), "TABLE_COLUMN_VISIBLE"); ! changeListenerHandler.registerChangeListener(column.sortNodeProperty(), "TABLE_COLUMN_SORT_NODE"); ! changeListenerHandler.registerChangeListener(column.sortableProperty(), "TABLE_COLUMN_SORTABLE"); ! changeListenerHandler.registerChangeListener(column.textProperty(), "TABLE_COLUMN_TEXT"); ! changeListenerHandler.registerChangeListener(column.graphicProperty(), "TABLE_COLUMN_GRAPHIC"); ! column.getStyleClass().addListener(weakStyleClassListener); ! setId(column.getId()); ! setStyle(column.getStyle()); updateStyleClass(); /* Having TableColumn role parented by TableColumn causes VoiceOver to be unhappy */ setAccessibleRole(AccessibleRole.TABLE_COLUMN); } } --- 124,196 ---- private int newColumnPos; // 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; /*************************************************************************** * * * Constructor * * * **************************************************************************/ + /** + * 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; ! setTableColumn(tc); this.columnReorderLine = skin.getColumnReorderLine(); setFocusTraversable(false); updateColumnIndex(); initUI(); // change listener for multiple properties ! changeListenerHandler = new LambdaMultiplePropertyChangeListenerHandler(); ! changeListenerHandler.registerChangeListener(sceneProperty(), e -> updateScene()); ! if (getTableColumn() != null && skin != null) { updateSortPosition(); skin.getSortOrder().addListener(weakSortOrderListener); skin.getVisibleLeafColumns().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 -> { ! // It is this that ensures that when a column is resized that the header ! // visually adjusts its width as necessary. ! isSizeDirty = true; ! requestLayout(); ! }); ! changeListenerHandler.registerChangeListener(tc.visibleProperty(), e -> setVisible(getTableColumn().isVisible())); ! changeListenerHandler.registerChangeListener(tc.sortNodeProperty(), e -> updateSortGrid()); ! 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 (skin.getSortOrder().contains(getTableColumn())) { ! NestedTableColumnHeader root = getTableHeaderRow().getRootHeader(); ! updateAllHeaders(root); ! } ! }); ! changeListenerHandler.registerChangeListener(tc.textProperty(), e -> label.setText(tc.getText())); ! changeListenerHandler.registerChangeListener(tc.graphicProperty(), e -> label.setGraphic(tc.getGraphic())); ! tc.getStyleClass().addListener(weakStyleClassListener); ! setId(tc.getId()); ! setStyle(tc.getStyle()); updateStyleClass(); /* Having TableColumn role parented by TableColumn causes VoiceOver to be unhappy */ setAccessibleRole(AccessibleRole.TABLE_COLUMN); } }
*** 183,193 **** * * * Listeners * * * **************************************************************************/ ! protected final MultiplePropertyChangeListenerHandler changeListenerHandler; private ListChangeListener<TableColumnBase<?,?>> sortOrderListener = c -> { updateSortPosition(); }; --- 201,211 ---- * * * Listeners * * * **************************************************************************/ ! final LambdaMultiplePropertyChangeListenerHandler changeListenerHandler; private ListChangeListener<TableColumnBase<?,?>> sortOrderListener = c -> { updateSortPosition(); };
*** 262,276 **** * * * Properties * * * **************************************************************************/ private DoubleProperty size; ! private double getSize() { return size == null ? 20.0 : size.doubleValue(); } ! private DoubleProperty sizeProperty() { if (size == null) { size = new StyleableDoubleProperty(20) { @Override protected void invalidated() { double value = get(); --- 280,295 ---- * * * Properties * * * **************************************************************************/ + // --- size private DoubleProperty size; ! private final double getSize() { return size == null ? 20.0 : size.doubleValue(); } ! private final DoubleProperty sizeProperty() { if (size == null) { size = new StyleableDoubleProperty(20) { @Override protected void invalidated() { double value = get();
*** 300,371 **** } return size; } ! ! /*************************************************************************** ! * * ! * Public Methods * ! * * ! **************************************************************************/ ! ! protected void handlePropertyChanged(String p) { ! if ("SCENE".equals(p)) { ! updateScene(); ! } else if ("TABLE_COLUMN_VISIBLE".equals(p)) { ! setVisible(getTableColumn().isVisible()); ! } else if ("TABLE_COLUMN_WIDTH".equals(p)) { ! // It is this that ensures that when a column is resized that the header ! // visually adjusts its width as necessary. ! isSizeDirty = true; ! requestLayout(); ! } else if ("TABLE_COLUMN_ID".equals(p)) { ! setId(column.getId()); ! } else if ("TABLE_COLUMN_STYLE".equals(p)) { ! setStyle(column.getStyle()); ! } else if ("TABLE_COLUMN_SORT_TYPE".equals(p)) { ! updateSortGrid(); ! if (arrow != null) { ! arrow.setRotate(isAscending(column) ? 180 : 0.0); ! } ! } else if ("TABLE_COLUMN_SORT_NODE".equals(p)) { ! updateSortGrid(); ! } else if ("TABLE_COLUMN_SORTABLE".equals(p)) { ! // 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 (skin.getSortOrder().contains(getTableColumn())) { ! NestedTableColumnHeader root = getTableHeaderRow().getRootHeader(); ! updateAllHeaders(root); ! } ! } else if ("TABLE_COLUMN_TEXT".equals(p)) { ! label.setText(column.getText()); ! } else if ("TABLE_COLUMN_GRAPHIC".equals(p)) { ! label.setGraphic(column.getGraphic()); } } ! ! protected TableViewSkinBase<?,?,?,?,?,TableColumnBase<?,?>> getTableViewSkin() { ! return skin; } - NestedTableColumnHeader getNestedColumnHeader() { return nestedColumnHeader; } - void setNestedColumnHeader(NestedTableColumnHeader nch) { nestedColumnHeader = nch; } - - public TableColumnBase getTableColumn() { return column; } - - TableHeaderRow getTableHeaderRow() { return tableHeaderRow; } - void setTableHeaderRow(TableHeaderRow thr) { tableHeaderRow = thr; } - - NestedTableColumnHeader getParentHeader() { return parentHeader; } - void setParentHeader(NestedTableColumnHeader ph) { parentHeader = ph; } - /*************************************************************************** * * ! * Layout * * * **************************************************************************/ /** {@inheritDoc} */ @Override protected void layoutChildren() { --- 319,349 ---- } return size; } ! /** ! * A property that refers to the {@link TableColumnBase} instance that this ! * header is visually represents. ! */ ! // --- table column ! private ReadOnlyObjectWrapper<TableColumnBase<?,?>> tableColumn = new ReadOnlyObjectWrapper<>(this, "tableColumn"); ! private final void setTableColumn(TableColumnBase<?,?> column) { ! tableColumn.set(column); } + public final TableColumnBase<?,?> getTableColumn() { + return tableColumn.get(); } ! public final ReadOnlyObjectProperty<TableColumnBase<?,?>> tableColumnProperty() { ! return tableColumn.getReadOnlyProperty(); } /*************************************************************************** * * ! * Public API * * * **************************************************************************/ /** {@inheritDoc} */ @Override protected void layoutChildren() {
*** 402,418 **** /** {@inheritDoc} */ @Override protected double computePrefWidth(double height) { if (getNestedColumnHeader() != null) { double width = getNestedColumnHeader().prefWidth(height); ! if (column != null) { ! column.impl_setWidth(width); } return width; ! } else if (column != null && column.isVisible()) { ! return column.getWidth(); } return 0; } --- 380,396 ---- /** {@inheritDoc} */ @Override protected double computePrefWidth(double height) { if (getNestedColumnHeader() != null) { double width = getNestedColumnHeader().prefWidth(height); ! if (getTableColumn() != null) { ! getTableColumn().impl_setWidth(width); } return width; ! } else if (getTableColumn() != null && getTableColumn().isVisible()) { ! return getTableColumn().getWidth(); } return 0; }
*** 425,442 **** --- 403,447 ---- @Override protected double computePrefHeight(double width) { if (getTableColumn() == null) return 0; return Math.max(getSize(), label.prefHeight(-1)); } + /** {@inheritDoc} */ + @Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { + return getClassCssMetaData(); + } + + /** {@inheritDoc} */ + @Override public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) { + switch (attribute) { + case INDEX: return getIndex(getTableColumn()); + case TEXT: return getTableColumn() != null ? getTableColumn().getText() : null; + default: return super.queryAccessibleAttribute(attribute, parameters); + } + } + /*************************************************************************** * * * Private Implementation * * * **************************************************************************/ + 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; } + + NestedTableColumnHeader getParentHeader() { return parentHeader; } + void setParentHeader(NestedTableColumnHeader ph) { parentHeader = ph; } + // RT-29682: When the sortable property of a TableColumnBase changes this // may impact other TableColumnHeaders, as they may need to change their // sort order representation. Rather than install listeners across all // TableColumn in the sortOrder list for their sortable property, we simply // update the sortPosition of all headers whenever the sortOrder property
*** 454,464 **** private void updateStyleClass() { // For now we leave the 'column-header' style class intact so that the // appropriate border styles are shown, etc. getStyleClass().setAll("column-header"); ! getStyleClass().addAll(column.getStyleClass()); } private void updateScene() { // RT-17684: If the TableColumn widths are all currently the default, // we attempt to 'auto-size' based on the preferred width of the first --- 459,469 ---- private void updateStyleClass() { // For now we leave the 'column-header' style class intact so that the // appropriate border styles are shown, etc. getStyleClass().setAll("column-header"); ! getStyleClass().addAll(getTableColumn().getStyleClass()); } private void updateScene() { // RT-17684: If the TableColumn widths are all currently the default, // we attempt to 'auto-size' based on the preferred width of the first
*** 493,521 **** return true; } private boolean isColumnReorderingEnabled() { // we only allow for column reordering if there are more than one column, ! return !BehaviorSkinBase.IS_TOUCH_SUPPORTED && getTableViewSkin().getVisibleLeafColumns().size() > 1; } private void initUI() { // TableColumn will be null if we are dealing with the root NestedTableColumnHeader ! if (column == null) return; // set up mouse events setOnMousePressed(mousePressedHandler); setOnMouseDragged(mouseDraggedHandler); setOnDragDetected(event -> event.consume()); setOnContextMenuRequested(contextMenuRequestedHandler); setOnMouseReleased(mouseReleasedHandler); // --- label label = new Label(); ! label.setText(column.getText()); ! label.setGraphic(column.getGraphic()); ! label.setVisible(column.isVisible()); // ---- container for the sort arrow (which is not supported on embedded // platforms) if (isSortingEnabled()) { // put together the grid --- 498,526 ---- return true; } private boolean isColumnReorderingEnabled() { // we only allow for column reordering if there are more than one column, ! return !Properties.IS_TOUCH_SUPPORTED && getTableViewSkin().getVisibleLeafColumns().size() > 1; } private void initUI() { // TableColumn will be null if we are dealing with the root NestedTableColumnHeader ! if (getTableColumn() == null) return; // set up mouse events setOnMousePressed(mousePressedHandler); setOnMouseDragged(mouseDraggedHandler); setOnDragDetected(event -> event.consume()); setOnContextMenuRequested(contextMenuRequestedHandler); setOnMouseReleased(mouseReleasedHandler); // --- label label = new Label(); ! label.setText(getTableColumn().getText()); ! label.setGraphic(getTableColumn().getGraphic()); ! label.setVisible(getTableColumn().isVisible()); // ---- container for the sort arrow (which is not supported on embedded // platforms) if (isSortingEnabled()) { // put together the grid
*** 531,541 **** getTableViewSkin().resizeColumnToFitContent(column, cellsToMeasure); } } private void updateSortPosition() { ! this.sortPos = ! column.isSortable() ? -1 : getSortPosition(); updateSortGrid(); } private void updateSortGrid() { // Fix for RT-14488 --- 536,546 ---- getTableViewSkin().resizeColumnToFitContent(column, cellsToMeasure); } } private void updateSortPosition() { ! this.sortPos = ! getTableColumn().isSortable() ? -1 : getSortPosition(); updateSortGrid(); } private void updateSortGrid() { // Fix for RT-14488
*** 575,586 **** // if we are here, and the sort arrow is null, we better create it if (arrow == null) { arrow = new Region(); arrow.getStyleClass().setAll("arrow"); arrow.setVisible(true); ! arrow.setRotate(isAscending(column) ? 180.0F : 0.0F); ! changeListenerHandler.registerChangeListener(getSortTypeProperty(column), "TABLE_COLUMN_SORT_TYPE"); } arrow.setVisible(isSortColumn); if (sortPos > 2) { --- 580,596 ---- // if we are here, and the sort arrow is null, we better create it if (arrow == null) { arrow = new Region(); arrow.getStyleClass().setAll("arrow"); arrow.setVisible(true); ! arrow.setRotate(isAscending(getTableColumn()) ? 180.0F : 0.0F); ! changeListenerHandler.registerChangeListener(getSortTypeProperty(getTableColumn()), e -> { ! updateSortGrid(); ! if (arrow != null) { ! arrow.setRotate(isAscending(getTableColumn()) ? 180 : 0.0); ! } ! }); } arrow.setVisible(isSortColumn); if (sortPos > 2) {
*** 605,615 **** sortOrderDots = new HBox(0); sortOrderDots.getStyleClass().add("sort-order-dots-container"); } // show the sort order dots ! boolean isAscending = isAscending(column); int arrowRow = isAscending ? 1 : 2; int dotsRow = isAscending ? 2 : 1; sortArrowGrid.add(arrow, 1, arrowRow); GridPane.setHalignment(arrow, HPos.CENTER); --- 615,625 ---- sortOrderDots = new HBox(0); sortOrderDots.getStyleClass().add("sort-order-dots-container"); } // show the sort order dots ! boolean isAscending = isAscending(getTableColumn()); int arrowRow = isAscending ? 1 : 2; int dotsRow = isAscending ? 2 : 1; sortArrowGrid.add(arrow, 1, arrowRow); GridPane.setHalignment(arrow, HPos.CENTER);
*** 639,649 **** for (int i = 0; i <= sortPos; i++) { Region r = new Region(); r.getStyleClass().add("sort-order-dot"); ! String sortTypeName = getSortTypeName(column); if (sortTypeName != null && ! sortTypeName.isEmpty()) { r.getStyleClass().add(sortTypeName.toLowerCase(Locale.ROOT)); } sortOrderDots.getChildren().add(r); --- 649,659 ---- for (int i = 0; i <= sortPos; i++) { Region r = new Region(); r.getStyleClass().add("sort-order-dot"); ! String sortTypeName = getSortTypeName(getTableColumn()); if (sortTypeName != null && ! sortTypeName.isEmpty()) { r.getStyleClass().add(sortTypeName.toLowerCase(Locale.ROOT)); } sortOrderDots.getChildren().add(r);
*** 736,760 **** private void sortColumn(final boolean addColumn) { if (! isSortingEnabled()) return; // we only allow sorting on the leaf columns and columns // that actually have comparators defined, and are sortable ! if (column == null || column.getColumns().size() != 0 || column.getComparator() == null || !column.isSortable()) return; // final int sortPos = getTable().getSortOrder().indexOf(column); // final boolean isSortColumn = sortPos != -1; final ObservableList<TableColumnBase<?,?>> sortOrder = getTableViewSkin().getSortOrder(); // addColumn is true e.g. when the user is holding down Shift if (addColumn) { if (!isSortColumn) { ! setSortType(column, TableColumn.SortType.ASCENDING); ! sortOrder.add(column); ! } else if (isAscending(column)) { ! setSortType(column, TableColumn.SortType.DESCENDING); } else { ! int i = sortOrder.indexOf(column); if (i != -1) { sortOrder.remove(i); } } } else { --- 746,770 ---- private void sortColumn(final boolean addColumn) { if (! isSortingEnabled()) return; // we only allow sorting on the leaf columns and columns // that actually have comparators defined, and are sortable ! if (getTableColumn() == null || getTableColumn().getColumns().size() != 0 || getTableColumn().getComparator() == null || !getTableColumn().isSortable()) return; // final int sortPos = getTable().getSortOrder().indexOf(column); // final boolean isSortColumn = sortPos != -1; final ObservableList<TableColumnBase<?,?>> sortOrder = getTableViewSkin().getSortOrder(); // addColumn is true e.g. when the user is holding down Shift if (addColumn) { if (!isSortColumn) { ! setSortType(getTableColumn(), TableColumn.SortType.ASCENDING); ! sortOrder.add(getTableColumn()); ! } else if (isAscending(getTableColumn())) { ! setSortType(getTableColumn(), TableColumn.SortType.DESCENDING); } else { ! int i = sortOrder.indexOf(getTableColumn()); if (i != -1) { sortOrder.remove(i); } } } else {
*** 764,819 **** // the column is already being sorted, and it's the only column. // We therefore move through the 2nd or 3rd states: // 1st click: sort ascending // 2nd click: sort descending // 3rd click: natural sorting (sorting is switched off) ! if (isAscending(column)) { ! setSortType(column, TableColumn.SortType.DESCENDING); } else { // remove from sort ! sortOrder.remove(column); } } else if (isSortColumn) { // the column is already being used to sort, so we toggle its // sortAscending property, and also make the column become the // primary sort column ! if (isAscending(column)) { ! setSortType(column, TableColumn.SortType.DESCENDING); ! } else if (isDescending(column)) { ! setSortType(column, TableColumn.SortType.ASCENDING); } // to prevent multiple sorts, we make a copy of the sort order // list, moving the column value from the current position to // its new position at the front of the list List<TableColumnBase<?,?>> sortOrderCopy = new ArrayList<TableColumnBase<?,?>>(sortOrder); ! sortOrderCopy.remove(column); ! sortOrderCopy.add(0, column); ! sortOrder.setAll(column); } else { // add to the sort order, in ascending form ! setSortType(column, TableColumn.SortType.ASCENDING); ! sortOrder.setAll(column); } } } // Because it is possible that some columns are in the sortOrder list but are // not themselves sortable, we cannot just do sortOrderList.indexOf(column). // Therefore, this method does the proper work required of iterating through // and ignoring non-sortable (and null) columns in the sortOrder list. private int getSortPosition() { ! if (column == null) { return -1; } final List<TableColumnBase> sortOrder = getVisibleSortOrderColumns(); int pos = 0; for (int i = 0; i < sortOrder.size(); i++) { TableColumnBase _tc = sortOrder.get(i); ! if (column.equals(_tc)) { return pos; } pos++; } --- 774,829 ---- // the column is already being sorted, and it's the only column. // We therefore move through the 2nd or 3rd states: // 1st click: sort ascending // 2nd click: sort descending // 3rd click: natural sorting (sorting is switched off) ! if (isAscending(getTableColumn())) { ! setSortType(getTableColumn(), TableColumn.SortType.DESCENDING); } else { // remove from sort ! sortOrder.remove(getTableColumn()); } } else if (isSortColumn) { // the column is already being used to sort, so we toggle its // sortAscending property, and also make the column become the // primary sort column ! if (isAscending(getTableColumn())) { ! setSortType(getTableColumn(), TableColumn.SortType.DESCENDING); ! } else if (isDescending(getTableColumn())) { ! setSortType(getTableColumn(), TableColumn.SortType.ASCENDING); } // to prevent multiple sorts, we make a copy of the sort order // list, moving the column value from the current position to // its new position at the front of the list List<TableColumnBase<?,?>> sortOrderCopy = new ArrayList<TableColumnBase<?,?>>(sortOrder); ! sortOrderCopy.remove(getTableColumn()); ! sortOrderCopy.add(0, getTableColumn()); ! sortOrder.setAll(getTableColumn()); } else { // add to the sort order, in ascending form ! setSortType(getTableColumn(), TableColumn.SortType.ASCENDING); ! sortOrder.setAll(getTableColumn()); } } } // Because it is possible that some columns are in the sortOrder list but are // not themselves sortable, we cannot just do sortOrderList.indexOf(column). // Therefore, this method does the proper work required of iterating through // and ignoring non-sortable (and null) columns in the sortOrder list. private int getSortPosition() { ! if (getTableColumn() == null) { return -1; } final List<TableColumnBase> sortOrder = getVisibleSortOrderColumns(); int pos = 0; for (int i = 0; i < sortOrder.size(); i++) { TableColumnBase _tc = sortOrder.get(i); ! if (getTableColumn().equals(_tc)) { return pos; } pos++; }
*** 852,875 **** * * **************************************************************************/ // package for testing void columnReorderingStarted(double dragOffset) { ! if (! column.impl_isReorderable()) return; // Used to ensure the column ghost is positioned relative to where the // user clicked on the column header this.dragOffset = dragOffset; // Note here that we only allow for reordering of 'root' columns ! getTableHeaderRow().setReorderingColumn(column); getTableHeaderRow().setReorderingRegion(this); } // package for testing void columnReordering(double sceneX, double sceneY) { ! if (! column.impl_isReorderable()) return; // this is for handling the column drag to reorder columns. // It shows a line to indicate where the 'drop' will be. // indicate that we've started dragging so that the dragging --- 862,885 ---- * * **************************************************************************/ // package for testing void columnReorderingStarted(double dragOffset) { ! if (! getTableColumn().impl_isReorderable()) return; // Used to ensure the column ghost is positioned relative to where the // user clicked on the column header this.dragOffset = dragOffset; // Note here that we only allow for reordering of 'root' columns ! getTableHeaderRow().setReorderingColumn(getTableColumn()); getTableHeaderRow().setReorderingRegion(this); } // package for testing void columnReordering(double sceneX, double sceneY) { ! if (! getTableColumn().impl_isReorderable()) return; // this is for handling the column drag to reorder columns. // It shows a line to indicate where the 'drop' will be. // indicate that we've started dragging so that the dragging
*** 924,934 **** double midPoint = startX + (endX - startX) / 2; boolean beforeMidPoint = x <= midPoint; // Based on where the mouse actually is, we have to shuffle // where we want the column to end up. This code handles that. ! int currentPos = getIndex(column); newColumnPos += newColumnPos > currentPos && beforeMidPoint ? -1 : (newColumnPos < currentPos && !beforeMidPoint ? 1 : 0); double lineX = getTableHeaderRow().sceneToLocal(hoverHeader.localToScene(hoverHeader.getBoundsInLocal())).getMinX(); lineX = lineX + ((beforeMidPoint) ? (0) : (hoverHeader.getWidth())); --- 934,944 ---- double midPoint = startX + (endX - startX) / 2; boolean beforeMidPoint = x <= midPoint; // Based on where the mouse actually is, we have to shuffle // where we want the column to end up. This code handles that. ! int currentPos = getIndex(getTableColumn()); newColumnPos += newColumnPos > currentPos && beforeMidPoint ? -1 : (newColumnPos < currentPos && !beforeMidPoint ? 1 : 0); double lineX = getTableHeaderRow().sceneToLocal(hoverHeader.localToScene(hoverHeader.getBoundsInLocal())).getMinX(); lineX = lineX + ((beforeMidPoint) ? (0) : (hoverHeader.getWidth()));
*** 946,956 **** getTableHeaderRow().setReordering(true); } // package for testing void columnReorderingComplete() { ! if (! column.impl_isReorderable()) return; // Move col from where it is now to the new position. moveColumn(getTableColumn(), newColumnPos); // cleanup --- 956,966 ---- getTableHeaderRow().setReordering(true); } // package for testing void columnReorderingComplete() { ! if (! getTableColumn().impl_isReorderable()) return; // Move col from where it is now to the new position. moveColumn(getTableColumn(), newColumnPos); // cleanup
*** 963,972 **** --- 973,986 ---- getTableHeaderRow().setReorderingColumn(null); getTableHeaderRow().setReorderingRegion(null); dragOffset = 0.0F; } + double getDragRectHeight() { + return getHeight(); + } + /*************************************************************************** * * * Stylesheet Handling *
*** 974,987 **** **************************************************************************/ private static final PseudoClass PSEUDO_CLASS_LAST_VISIBLE = PseudoClass.getPseudoClass("last-visible"); - double getDragRectHeight() { - return getHeight(); - } - /** * Super-lazy instantiation pattern from Bill Pugh. * @treatAsPrivate implementation detail */ private static class StyleableProperties { --- 988,997 ----
*** 1010,1038 **** } } /** ! * @return The CssMetaData associated with this class, which may include the * CssMetaData of its super classes. */ public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { return StyleableProperties.STYLEABLES; } - - /** - * {@inheritDoc} - */ - @Override public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { - return getClassCssMetaData(); - } - - @Override - public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) { - switch (attribute) { - case INDEX: return getIndex(column); - case TEXT: return column != null ? column.getText() : null; - default: return super.queryAccessibleAttribute(attribute, parameters); - } - } - } --- 1020,1031 ---- } } /** ! * Returnst he CssMetaData associated with this class, which may include the * CssMetaData of its super classes. */ public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { return StyleableProperties.STYLEABLES; } }