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 26 package javafx.scene.control.test.Mnemonics; 27 28 import java.util.ArrayList; 29 import javafx.geometry.Point2D; 30 import javafx.scene.Node; 31 import javafx.scene.Scene; 32 import javafx.scene.control.Labeled; 33 import javafx.scene.control.test.ControlsTestBase; 34 import javafx.scene.shape.Line; 35 import javafx.scene.text.Text; 36 import org.jemmy.Rectangle; 37 import org.jemmy.action.GetAction; 38 import org.jemmy.control.Wrap; 39 import org.jemmy.fx.ByStyleClass; 40 import org.jemmy.fx.Root; 41 import org.jemmy.interfaces.Keyboard; 42 import org.jemmy.interfaces.Keyboard.KeyboardButton; 43 import org.jemmy.interfaces.Keyboard.KeyboardButtons; 44 import org.jemmy.interfaces.Parent; 45 import org.jemmy.lookup.LookupCriteria; 46 import org.jemmy.timing.State; 47 import static org.junit.Assert.*; 48 import org.junit.Before; 49 import org.junit.BeforeClass; 50 import test.javaclient.shared.Utils; 51 52 public class MnemonicsTestBase extends ControlsTestBase { 53 54 static Wrap<? extends Scene> scene = null; 55 static Parent<Node> sceneAsParent = null; 56 57 static final String MNEMONIC_UNDERLINE_STYLE_CLASS = "mnemonic-underline"; 58 59 static boolean isLinux; 60 61 //If test is run on Linux this modifier is used to invoke mnemonics 62 //along with the key assigned to the control. 63 static Keyboard.KeyboardModifiers[] mod; 64 65 @BeforeClass 66 public static void setUpClass() throws Exception { 67 scene = Root.ROOT.lookup().wrap(); 68 sceneAsParent = scene.as(Parent.class, Node.class); 69 70 isLinux = Utils.isLinux(); 71 mod = isLinux ? new Keyboard.KeyboardModifiers[]{Keyboard.KeyboardModifiers.ALT_DOWN_MASK} : new Keyboard.KeyboardModifiers[]{}; 72 } 73 74 @Before 75 public void setUp() { 76 } 77 78 protected static void removeFocus(Wrap<? extends Node> ... wraps) { 79 boolean focused; 80 do { 81 focused = false; 82 for (Wrap<? extends Node> wrap : wraps) { 83 if (wrap.getProperty(java.lang.Boolean.class, "isFocused")) { 84 scene.keyboard().pushKey(KeyboardButtons.TAB); 85 wrap.waitProperty("isFocused", Boolean.FALSE); 86 focused = true; 87 } 88 } 89 } while (focused == true); 90 91 for (Wrap<? extends Node> wrap : wraps) { 92 if (wrap.getProperty(java.lang.Boolean.class, "isFocused")) { 93 wrap.waitProperty("isFocused", Boolean.FALSE); 94 } 95 } 96 } 97 98 protected static void checkUnderline(Wrap<? extends Node> wrap, Boolean exist) throws Throwable { 99 if (!exist && wrap.as(Parent.class, Node.class).lookup(Line.class, new ByStyleClass(MNEMONIC_UNDERLINE_STYLE_CLASS)).size() == 0 ) { 100 return; 101 } 102 final Wrap<? extends Line> underline_wrap = wrap.as(Parent.class, Node.class).lookup(Line.class, new ByStyleClass(MNEMONIC_UNDERLINE_STYLE_CLASS)).wrap(); 103 underline_wrap.waitState(new State<Boolean>() { 104 public Boolean reached() { 105 return new GetAction<Boolean>() { 106 @Override 107 public void run(Object... os) throws Exception { 108 final Line control = underline_wrap.getControl(); 109 setResult(control.getStroke().isOpaque() && control.isVisible() && (control.getOpacity() == 1.0)); 110 } 111 }.dispatch(underline_wrap.getEnvironment()); 112 } 113 }, exist); 114 if (exist) { 115 final Wrap<? extends Text> text_wrap = wrap.as(Parent.class, Node.class).lookup(Text.class).wrap(); 116 Rectangle text_bounds = text_wrap.getScreenBounds(); 117 final String str = text_wrap.as(org.jemmy.interfaces.Text.class).text(); 118 ArrayList<Rectangle> bounds_array = new ArrayList<Rectangle>(); 119 for (int i = 0; i < str.length() + 1; i++) { 120 bounds_array.add(null); 121 } 122 for (int y = 0; y < text_bounds.height; y++) { 123 for (int x = 0; x < text_bounds.width; x++) { 124 final Text control = text_wrap.getControl(); 125 final int charIndex = new GetAction<Integer>() { 126 public void run(Object... os) throws Exception { 127 setResult(control.hitTest(new Point2D((Integer)os[0], (Integer)os[1] - control.getBaselineOffset())).getCharIndex()); 128 } 129 }.dispatch(wrap.getEnvironment(), x, y); 130 if (bounds_array.get(charIndex) == null) { 131 bounds_array.set(charIndex, new Rectangle(x, y, 0, 0)); 132 } else { 133 bounds_array.get(charIndex).add(x, y); 134 } 135 } 136 } 137 int underline_index = -1; 138 if (wrap.is(org.jemmy.interfaces.Text.class)) { 139 underline_index = wrap.as(org.jemmy.interfaces.Text.class).text().indexOf("_"); 140 } else { 141 final Wrap<? extends Labeled> sub_wrap = wrap.as(Parent.class, Node.class).lookup(new LookupCriteria<Node>() { 142 public boolean check(Node cntrl) { 143 return cntrl instanceof Labeled; 144 } 145 }).wrap(); 146 underline_index = sub_wrap.as(org.jemmy.interfaces.Text.class).text().indexOf("_"); 147 } 148 Rectangle underlined_char_bounds = bounds_array.get(underline_index); 149 underlined_char_bounds.translate(text_bounds.x, text_bounds.y); 150 Rectangle suggested_rect = new Rectangle(underlined_char_bounds.x - 2, underlined_char_bounds.y + underlined_char_bounds.height - 1, 151 underlined_char_bounds.width + 4, text_bounds.height - underlined_char_bounds.height + 1); 152 assertTrue(suggested_rect.contains(underline_wrap.getScreenBounds())); 153 } 154 } 155 156 protected static KeyboardButton getButton(Wrap<? extends Labeled> wrap) { 157 String text = wrap.getControl().getText(); 158 int index = text.indexOf("_"); 159 String letter = text.substring(index + 1, index + 2).toUpperCase(); 160 try { 161 Integer.parseInt(letter); 162 } catch (Exception ex) { 163 return KeyboardButtons.valueOf(letter); 164 } 165 return KeyboardButtons.valueOf("D" + letter); 166 } 167 }