1 /* 2 * Copyright (c) 2009, 2012, 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 package org.jemmy.fx.control; 26 27 import javafx.scene.control.skin.VirtualFlow; 28 import javafx.collections.ObservableList; 29 import javafx.scene.control.*; 30 import org.jemmy.Point; 31 import org.jemmy.action.FutureAction; 32 import org.jemmy.control.As; 33 import org.jemmy.control.ControlInterfaces; 34 import org.jemmy.control.ControlType; 35 import org.jemmy.control.Property; 36 import org.jemmy.env.Environment; 37 import org.jemmy.fx.control.Scrollable2DImpl.ScrollsLookupCriteria; 38 import org.jemmy.interfaces.EditableCellOwner; 39 import org.jemmy.interfaces.Focusable; 40 import org.jemmy.interfaces.Scrollable2D; 41 import org.jemmy.interfaces.Table; 42 43 import java.util.ArrayList; 44 45 /** 46 * Table support in JemmyFX is provided through 47 * <code>Table</code> and 48 * <code>Parent</code> control interfaces. 49 * 50 * @param <CONTROL> 51 * @author shura 52 * @see #asItemParent(java.lang.Class) 53 * @see #asTable(java.lang.Class) 54 * @see #asTableCellItemParent(java.lang.Class) 55 * @see TableViewDock 56 */ 57 @ControlType({TableView.class}) 58 @ControlInterfaces(value = {Table.class, Scrollable2D.class}, 59 encapsulates = {Object.class}) 60 public class TableViewWrap<CONTROL extends TableView> extends ControlWrap<CONTROL> implements Focusable { 61 62 public static final String DATA_COLUMNS_PROP_NAME = "data.columns"; 63 public static final String COLUMNS_PROP_NAME = "columns"; 64 public static final String ITEMS_PROP_NAME = "items"; 65 public static final String SELECTION_PROP_NAME = "selection"; 66 public static final String ITEMS_COUNT_PROP_NAME = "item.count"; 67 private TableTreeScroll scroll; 68 private Scrollable2D scrollable2D; 69 private TableCellItemParent parent; 70 71 /** 72 * TableViewWrap is a wrap for TableView control of JavaFX 73 * 74 * @param env 75 * @param nd 76 */ 77 public TableViewWrap(Environment env, CONTROL nd) { 78 super(env, nd); 79 } 80 81 /** 82 * Gives a size of a list of objects (rows) displayed in the table. 83 * 84 * @return 85 */ 86 @Property(ITEMS_COUNT_PROP_NAME) 87 public int getSize() { 88 return new FutureAction<>(getEnvironment(), () -> getControl().getItems().size()).get(); 89 } 90 91 /** 92 * Gives a list of objects (rows) displayed in the table. 93 * 94 * @return 95 */ 96 @Property(ITEMS_PROP_NAME) 97 public ObservableList getItems() { 98 return new FutureAction<>(getEnvironment(), () -> getControl().getItems()).get(); 99 } 100 101 /** 102 * Gives a selection. 103 * 104 * @return 105 */ 106 @Property(SELECTION_PROP_NAME) 107 public java.util.List<Point> selection() { 108 return new FutureAction<>(getEnvironment(), () -> { 109 java.util.List<Point> res = new ArrayList<>(); 110 for (TablePosition tp : (java.util.List<TablePosition>) getControl().getSelectionModel().getSelectedCells()) { 111 res.add(new Point(tp.getColumn(), tp.getRow())); 112 } 113 return res; 114 }).get(); 115 } 116 117 Object getRow(final int index) { 118 return new FutureAction<>(getEnvironment(), () -> getControl().getItems().get(index)).get(); 119 } 120 121 TableColumn getColumn(final int index) { 122 return new FutureAction<>(getEnvironment(), () -> (TableColumn) getControl().getColumns().get(index)).get(); 123 124 } 125 126 /** 127 * @return list of columns. 128 */ 129 @Property(COLUMNS_PROP_NAME) 130 public java.util.List<TableColumn> getColumns() { 131 return new FutureAction<>(getEnvironment(), () -> getControl().getColumns()).get(); 132 } 133 134 /** 135 * @return List of columns, which are on the last level (leaf columns) of 136 * table header. In the case of nested columns, some columns are parents, 137 * and some are children. This method returns the list of columns, which 138 * have no children. Those columns correspond to the realy shown columns of 139 * data in TableView. 140 */ 141 @Property(DATA_COLUMNS_PROP_NAME) 142 public java.util.List<TableColumn> getDataColumns() { 143 return new FutureAction<>(getEnvironment(), () -> { 144 ArrayList fillList = new ArrayList<TableColumn>(); 145 getLastLevelColumns((java.util.List<? extends TableColumnBase>) getControl().getColumns(), fillList); 146 return (java.util.List<TableColumn>) fillList; 147 }).get(); 148 } 149 150 protected static void getLastLevelColumns(java.util.List<? extends TableColumnBase> columnsToSearchIn, java.util.List fillingList) { 151 for (TableColumnBase column : columnsToSearchIn) { 152 if (column.getColumns().size() > 0) { 153 getLastLevelColumns(column.getColumns(), fillingList); 154 } else { 155 fillingList.add(column); 156 } 157 } 158 } 159 160 /** 161 * Jemmy table control interface introduces multiple selections mechanism. 162 * 163 * @param <T> 164 * @param type 165 * @return 166 */ 167 @As(Object.class) 168 public <T> Table<T> asTable(Class<T> type) { 169 return asTableCellItemParent(type); 170 } 171 172 @As 173 public Scrollable2D asScrollable2D() { 174 if (scrollable2D == null) { 175 scrollable2D = new Scrollable2DImpl(this, new ScrollsLookupCriteria() { 176 @Override 177 public boolean checkFor(ScrollBar scrollBar) { 178 return ((scrollBar.getParent() instanceof VirtualFlow) 179 && (scrollBar.getParent().getParent() instanceof TableView)); 180 } 181 }); 182 } 183 return scrollable2D; 184 } 185 186 /** 187 * You could find items within table and operate with them just like with 188 * any other UI elements. 189 * 190 * @param <T> 191 * @param type 192 * @return 193 * @see TableCellItemWrap 194 */ 195 @As(Object.class) 196 public <T> EditableCellOwner<T> asItemParent(Class<T> type) { 197 return asTableCellItemParent(type); 198 } 199 200 void scrollTo(int row, int column) { 201 if (scroll == null) { 202 scroll = new TableTreeScroll(this); 203 } 204 scroll.checkScrolls(); 205 TableUtils.<TableCell>scrollTo(getEnvironment(), this, scroll.hScroll, 206 scroll.vScroll, row, column, 207 new TableUtils.TableViewIndexInfoProvider(this), TableCell.class); 208 } 209 210 private <T> TableCellItemParent<T> asTableCellItemParent(Class<T> type) { 211 if (parent == null || !parent.getType().equals(type)) { 212 parent = new TableCellItemParent<>(this, type); 213 } 214 return parent; 215 } 216 217 protected int getRowIndex(IndexedCell tableCell) { 218 return ((TableCell) tableCell).getTableRow().getIndex(); 219 } 220 221 protected int getColumnIndex(IndexedCell tableCell) { 222 return ((TableCell) tableCell).getTableView().getVisibleLeafIndex(((TableCell) tableCell).getTableColumn()); 223 } 224 }