1 /* 2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.scene.control.skin; 27 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 import javafx.beans.property.DoubleProperty; 33 import javafx.scene.control.TableCell; 34 import javafx.scene.control.TableColumn; 35 import javafx.scene.control.TablePosition; 36 import javafx.scene.control.TableRow; 37 import javafx.scene.control.TableView; 38 39 import com.sun.javafx.scene.control.behavior.CellBehaviorBase; 40 import com.sun.javafx.scene.control.behavior.TableRowBehavior; 41 42 import javafx.beans.property.ObjectProperty; 43 import javafx.collections.FXCollections; 44 import javafx.collections.ObservableList; 45 import javafx.scene.AccessibleAttribute; 46 import javafx.scene.Node; 47 import javafx.scene.control.Control; 48 import javafx.scene.control.TableColumnBase; 49 import javafx.scene.control.TableView.TableViewFocusModel; 50 51 /** 52 */ 53 public class TableRowSkin<T> extends TableRowSkinBase<T, TableRow<T>, CellBehaviorBase<TableRow<T>>, TableCell<T,?>> { 54 55 private TableView<T> tableView; 56 private TableViewSkin<T> tableViewSkin; 57 58 public TableRowSkin(TableRow<T> tableRow) { 59 super(tableRow, new TableRowBehavior<T>(tableRow)); 60 61 this.tableView = tableRow.getTableView(); 62 updateTableViewSkin(); 63 64 super.init(tableRow); 65 66 registerChangeListener(tableRow.tableViewProperty(), "TABLE_VIEW"); 67 } 68 69 @Override protected void handleControlPropertyChanged(String p) { 70 super.handleControlPropertyChanged(p); 71 if ("TABLE_VIEW".equals(p)) { 72 updateTableViewSkin(); 73 74 for (int i = 0, max = cells.size(); i < max; i++) { 75 Node n = cells.get(i); 76 if (n instanceof TableCell) { 77 ((TableCell)n).updateTableView(getSkinnable().getTableView()); 78 } 79 } 80 81 this.tableView = getSkinnable().getTableView(); 82 } 83 } 84 85 @Override protected TableCell<T, ?> getCell(TableColumnBase tcb) { 86 TableColumn tableColumn = (TableColumn<T,?>) tcb; 87 TableCell cell = (TableCell) tableColumn.getCellFactory().call(tableColumn); 88 89 // we set it's TableColumn, TableView and TableRow 90 cell.updateTableColumn(tableColumn); 91 cell.updateTableView(tableColumn.getTableView()); 92 cell.updateTableRow(getSkinnable()); 93 94 return cell; 95 } 96 97 @Override protected ObservableList<TableColumn<T, ?>> getVisibleLeafColumns() { 98 return tableView.getVisibleLeafColumns(); 99 } 100 101 @Override protected void updateCell(TableCell<T, ?> cell, TableRow<T> row) { 102 cell.updateTableRow(row); 103 } 104 105 @Override protected DoubleProperty fixedCellSizeProperty() { 106 return tableView.fixedCellSizeProperty(); 107 } 108 109 @Override protected boolean isColumnPartiallyOrFullyVisible(TableColumnBase tc) { 110 return tableViewSkin == null ? false : tableViewSkin.isColumnPartiallyOrFullyVisible((TableColumn)tc); 111 } 112 113 @Override protected TableColumn<T, ?> getTableColumnBase(TableCell<T, ?> cell) { 114 return cell.getTableColumn(); 115 } 116 117 @Override protected ObjectProperty<Node> graphicProperty() { 118 return null; 119 } 120 121 @Override protected Control getVirtualFlowOwner() { 122 return getSkinnable().getTableView(); 123 } 124 125 private void updateTableViewSkin() { 126 TableView<T> tableView = getSkinnable().getTableView(); 127 if (tableView.getSkin() instanceof TableViewSkin) { 128 tableViewSkin = (TableViewSkin)tableView.getSkin(); 129 } 130 } 131 132 @Override 133 protected Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) { 134 switch (attribute) { 135 case SELECTED_ITEMS: { 136 // FIXME this could be optimised to iterate over cellsMap only 137 // (selectedCells could be big, cellsMap is much smaller) 138 List<Node> selection = new ArrayList<>(); 139 int index = getSkinnable().getIndex(); 140 for (TablePosition<T,?> pos : tableView.getSelectionModel().getSelectedCells()) { 141 if (pos.getRow() == index) { 142 TableColumn<T,?> column = pos.getTableColumn(); 143 if (column == null) { 144 /* This is the row-based case */ 145 column = tableView.getVisibleLeafColumn(0); 146 } 147 TableCell<T,?> cell = cellsMap.get(column).get(); 148 if (cell != null) selection.add(cell); 149 } 150 return FXCollections.observableArrayList(selection); 151 } 152 } 153 case CELL_AT_ROW_COLUMN: { 154 int colIndex = (Integer)parameters[1]; 155 TableColumn<T,?> column = tableView.getVisibleLeafColumn(colIndex); 156 if (cellsMap.containsKey(column)) { 157 return cellsMap.get(column).get(); 158 } 159 return null; 160 } 161 case FOCUS_ITEM: { 162 TableViewFocusModel<T> fm = tableView.getFocusModel(); 163 TablePosition<T,?> focusedCell = fm.getFocusedCell(); 164 TableColumn<T,?> column = focusedCell.getTableColumn(); 165 if (column == null) { 166 /* This is the row-based case */ 167 column = tableView.getVisibleLeafColumn(0); 168 } 169 if (cellsMap.containsKey(column)) { 170 return cellsMap.get(column).get(); 171 } 172 return null; 173 } 174 default: return super.queryAccessibleAttribute(attribute, parameters); 175 } 176 } 177 178 }