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;
}
}