1 /* 2 * Copyright (c) 2014, 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 javafx.scene.control.test.utils.ptables; 26 27 import java.lang.reflect.Method; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Comparator; 31 import java.util.List; 32 import javafx.beans.property.*; 33 import javafx.collections.FXCollections; 34 import javafx.collections.ObservableList; 35 import javafx.scene.Cursor; 36 import javafx.scene.ImageCursor; 37 import javafx.scene.Node; 38 import javafx.scene.control.ContextMenu; 39 import javafx.scene.control.Label; 40 import javafx.scene.control.MenuItem; 41 import javafx.scene.control.TableColumn; 42 import javafx.scene.control.Tooltip; 43 import javafx.scene.control.test.utils.ComponentsFactory; 44 import javafx.scene.image.Image; 45 import javafx.scene.paint.Color; 46 import javafx.scene.shape.Circle; 47 import javafx.scene.shape.PolygonBuilder; 48 import javafx.scene.shape.Rectangle; 49 import javafx.scene.text.Font; 50 import javafx.scene.text.Text; 51 import java.time.chrono.Chronology; 52 53 /** 54 * @author Alexander Kirov 55 * 56 * NOTION: this class should be instantiated on JavaFX thread. 57 */ 58 public class PropertyTablesFactory { 59 60 static ObservableList<String> excludeList = FXCollections.observableArrayList(); 61 62 static { 63 /* 64 * These properties are from Node so they are not needed for control 65 * testing. They can anyway be added manually to the accordiong 66 * PropertiesTable. 67 */ 68 excludeList.addAll("id", "blendMode", "cache", "style", "clip", "cacheHint", "depthTest", 69 "pickOnBounds", "managed", "layoutX", "layoutY", "layoutZ", "scene", "needsLayout", 70 "translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ", 71 "minWidth", "maxWidth", "minHeight", "maxHeight", "impl_showMnemonics"); 72 } 73 74 private static boolean propertyIsExculded(String propertyName) { 75 return excludeList.contains(propertyName); 76 } 77 78 public static void explorePropertiesList(Object control, PropertiesTable tb) { 79 Method[] all_methods = control.getClass().getMethods(); 80 for (Method method : all_methods) { 81 try { 82 if (method.getName().endsWith("Property")) { 83 String propertyName = method.getName().substring(0, method.getName().indexOf("Property")); 84 if (!propertyIsExculded(propertyName)) { 85 Class storedObjectClass = null; 86 87 try { 88 Method getter = control.getClass().getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1, propertyName.length())); 89 storedObjectClass = getter.getReturnType(); 90 } catch (Exception ex) { 91 } 92 93 if (method.getReturnType() == ObjectProperty.class) { 94 if ((method.getReturnType().getGenericInterfaces().length > 0)) { 95 if (storedObjectClass == Tooltip.class) { 96 provideTooltipObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 97 } 98 99 if (storedObjectClass == Comparator.class) { 100 provideComparatorPropertyLine((ObjectProperty) method.invoke(control), tb, control); 101 } 102 103 if (storedObjectClass == ContextMenu.class) { 104 provideContextMenuObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 105 } 106 107 if (storedObjectClass == Cursor.class) { 108 provideCursorObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 109 } 110 111 if (storedObjectClass == Font.class) { 112 provideFontObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 113 } 114 115 if (storedObjectClass == Node.class) { 116 provideCustomNodeObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 117 } 118 119 if (storedObjectClass == Chronology.class) { 120 provideChronologyObjectEnumPropertyLine((ObjectProperty) method.invoke(control), tb, control); 121 } 122 123 if (!(storedObjectClass == null) && storedObjectClass.isEnum()) { 124 tb.addObjectEnumPropertyLine((ObjectProperty) method.invoke(control), Arrays.asList(storedObjectClass.getEnumConstants()), control); 125 } 126 } 127 } 128 if (method.getReturnType() == DoubleProperty.class) { 129 PropertiesConstraints.NumericConstraints constr = PropertiesConstraints.getNumericConstraint(propertyName); 130 tb.addDoublePropertyLine((DoubleProperty) method.invoke(control), constr.min, constr.max, constr.default_value, control); 131 } 132 if (method.getReturnType() == IntegerProperty.class) { 133 PropertiesConstraints.NumericConstraints constr = PropertiesConstraints.getNumericConstraint(propertyName); 134 tb.addIntegerPropertyLine((IntegerProperty) method.invoke(control), (int) Math.round(constr.min), (int) Math.round(constr.max), (int) Math.round(constr.default_value)); 135 } 136 if (method.getReturnType() == StringProperty.class) { 137 tb.addStringLine((Property) method.invoke(control), "Some text"); 138 } 139 if (method.getReturnType() == BooleanProperty.class) { 140 tb.addBooleanPropertyLine((Property) method.invoke(control), control); 141 } 142 143 try { 144 Object ob = method.invoke(control); 145 if (ob.getClass().getName().contains("ReadOnly")) { 146 tb.addSimpleListener((ReadOnlyProperty) ob, control); 147 } 148 } catch (Exception ex) { 149 } 150 } 151 } 152 } catch (Throwable ex) { 153 System.err.println("Was an error, on invoke the method : " + method + ", parsing control " + control); 154 ex.printStackTrace(System.out); 155 } 156 } 157 } 158 159 public static void provideFontObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 160 List possibleFonts = new ArrayList(); 161 possibleFonts.add(null); 162 possibleFonts.add(new Font(20)); 163 possibleFonts.add(new Font("ArialW7", 15)); 164 possibleFonts.add(new Font("Verdana", 10)); 165 tb.addObjectEnumPropertyLine(property, possibleFonts, owningObject); 166 } 167 168 public static Tooltip provideTooltipObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 169 Tooltip tp = new Tooltip("Tooltip"); 170 List possibleTooltips = new ArrayList(); 171 possibleTooltips.add(null); 172 possibleTooltips.add(tp); 173 tb.addObjectEnumPropertyLine(property, possibleTooltips, owningObject); 174 return tp; 175 } 176 177 public static ContextMenu provideContextMenuObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 178 ContextMenu cm = new ContextMenu(); 179 cm.getItems().add(new MenuItem("SomeItem")); 180 List possibleMenus = new ArrayList(); 181 possibleMenus.add(null); 182 possibleMenus.add(cm); 183 tb.addObjectEnumPropertyLine(property, possibleMenus, owningObject); 184 return cm; 185 } 186 187 public static void provideCustomNodeObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 188 List possibleNodes = new ArrayList(); 189 possibleNodes.add(null); 190 possibleNodes.add(new Text("This is custom node")); 191 possibleNodes.add(new Label("Label text", new Text("Label node"))); 192 possibleNodes.add(new Rectangle(0, 0, 10, 10)); 193 possibleNodes.add(ComponentsFactory.createCustomContent(25, 25)); 194 possibleNodes.add(new Circle(6.75, Color.RED)); 195 possibleNodes.add(PolygonBuilder.create().fill(Color.GREEN).points(new Double[]{ 196 0.0, 7.0, 197 5.0, 20.0, 198 15.0, 20.0, 199 20.0, 7.0, 200 10.0, 0.0,}).build()); 201 tb.addObjectEnumPropertyLine(property, possibleNodes, owningObject); 202 } 203 204 // public static void provideChronologyObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 205 // List possibleChronologies = new ArrayList(); 206 // possibleChronologies.add(null); 207 // possibleChronologies.addAll(java.time.chrono.Chronology.getAvailableChronologies()); 208 // tb.addObjectEnumPropertyLine(property, possibleChronologies, owningObject); 209 // } 210 211 public static Cursor provideCursorObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 212 ImageCursor c1 = new ImageCursor(new Image("https://svn.java.net/svn/fxtest-golden~images-svn/ControlsTests/JavaProgBarInd80x80.gif")); 213 List possibleTooltips = new ArrayList(); 214 possibleTooltips.add(null); 215 possibleTooltips.add(c1); 216 tb.addObjectEnumPropertyLine(property, possibleTooltips, owningObject); 217 return c1; 218 } 219 220 public static void provideComparatorPropertyLine(ObjectProperty property, PropertiesTable tb, Object owningObject) { 221 List possibleComparators = new ArrayList(); 222 possibleComparators.add(null); 223 possibleComparators.add(new CustomReversedComparator()); 224 possibleComparators.add(TableColumn.DEFAULT_COMPARATOR); 225 tb.addObjectEnumPropertyLine(property, possibleComparators, owningObject); 226 } 227 228 private static void provideChronologyObjectEnumPropertyLine(ObjectProperty property, PropertiesTable tb, Object control) { 229 ArrayList<Chronology> values = new ArrayList<Chronology>(); 230 values.add(null); 231 values.add(Chronology.of("ISO")); 232 values.add(Chronology.of("Minguo")); 233 values.add(Chronology.of("ThaiBuddhist")); 234 values.add(Chronology.of("Japanese")); 235 values.add(Chronology.of("Hijrah-umalqura")); 236 237 tb.addObjectEnumPropertyLine(property, values, control); 238 } 239 240 public static class CustomReversedComparator implements Comparator { 241 //This is reversed comparator. 242 243 public static final String comparatorName = "Custom reversed comparator"; 244 245 public int compare(Object t1, Object t2) { 246 return -t1.toString().compareTo(t2.toString()); 247 } 248 249 @Override 250 public String toString() { 251 return comparatorName; 252 } 253 } 254 }