TextKeyboardDriver.java revision 13978:1993af50385d
1/* 2 * Copyright (c) 1997, 2016, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.netbeans.jemmy.drivers.text; 24 25import java.awt.event.InputEvent; 26import java.awt.event.KeyEvent; 27 28import org.netbeans.jemmy.CharBindingMap; 29import org.netbeans.jemmy.QueueTool; 30import org.netbeans.jemmy.Timeout; 31import org.netbeans.jemmy.drivers.DriverManager; 32import org.netbeans.jemmy.drivers.KeyDriver; 33import org.netbeans.jemmy.drivers.LightSupportiveDriver; 34import org.netbeans.jemmy.drivers.TextDriver; 35import org.netbeans.jemmy.operators.ComponentOperator; 36 37/** 38 * Superclass for all TextDrivers using keyboard. 39 * 40 * @author Alexandre Iline(alexandre.iline@oracle.com) 41 */ 42public abstract class TextKeyboardDriver extends LightSupportiveDriver implements TextDriver { 43 44 /** 45 * Constructs a TextKeyboardDriver. 46 * 47 * @param supported an array of supported class names 48 */ 49 public TextKeyboardDriver(String[] supported) { 50 super(supported); 51 } 52 53 @Override 54 public void changeCaretPosition(ComponentOperator oper, int position) { 55 DriverManager.getFocusDriver(oper).giveFocus(oper); 56 checkSupported(oper); 57 changeCaretPosition(oper, position, 0); 58 } 59 60 @Override 61 public void selectText(ComponentOperator oper, int startPosition, int finalPosition) { 62 changeCaretPosition(oper, startPosition); 63 DriverManager.getKeyDriver(oper).pressKey(oper, KeyEvent.VK_SHIFT, 0); 64 changeCaretPosition(oper, finalPosition, InputEvent.SHIFT_MASK); 65 DriverManager.getKeyDriver(oper).releaseKey(oper, KeyEvent.VK_SHIFT, 0); 66 } 67 68 @Override 69 public void clearText(ComponentOperator oper) { 70 DriverManager.getFocusDriver(oper).giveFocus(oper); 71 checkSupported(oper); 72 KeyDriver kdriver = DriverManager.getKeyDriver(oper); 73 Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"); 74 Timeout betweenTime = getBetweenTimeout(oper); 75 while (getCaretPosition(oper) > 0) { 76 kdriver.typeKey(oper, KeyEvent.VK_BACK_SPACE, (char) KeyEvent.VK_BACK_SPACE, 0, pushTime); 77 betweenTime.sleep(); 78 } 79 while (getText(oper).length() > 0) { 80 kdriver.pushKey(oper, KeyEvent.VK_DELETE, 0, pushTime); 81 betweenTime.sleep(); 82 } 83 } 84 85 @Override 86 public void typeText(ComponentOperator oper, String text, int caretPosition) { 87 changeCaretPosition(oper, caretPosition); 88 KeyDriver kDriver = DriverManager.getKeyDriver(oper); 89 CharBindingMap map = oper.getCharBindingMap(); 90 Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"); 91 Timeout betweenTime = getBetweenTimeout(oper); 92 char[] crs = text.toCharArray(); 93 for (char cr : crs) { 94 kDriver.typeKey(oper, map.getCharKey(cr), cr, map.getCharModifiers(cr), pushTime); 95 betweenTime.sleep(); 96 } 97 } 98 99 @Override 100 public void changeText(ComponentOperator oper, String text) { 101 clearText(oper); 102 typeText(oper, text, 0); 103 } 104 105 @Override 106 public void enterText(ComponentOperator oper, String text) { 107 changeText(oper, text); 108 DriverManager.getKeyDriver(oper).pushKey(oper, KeyEvent.VK_ENTER, 0, 109 new Timeout("", 0)); 110 } 111 112 /** 113 * Returns operator's text. 114 * 115 * @param oper an operator. 116 * @return string representing component text. 117 */ 118 public abstract String getText(ComponentOperator oper); 119 120 /** 121 * Returns current caret position. 122 * 123 * @param oper an operator. 124 * @return int represnting current operator's caret position. 125 */ 126 public abstract int getCaretPosition(ComponentOperator oper); 127 128 /** 129 * Returns a caret position of selection start. 130 * 131 * @param oper an operator. 132 * @return int represnting index of operator's selection start. 133 */ 134 public abstract int getSelectionStart(ComponentOperator oper); 135 136 /** 137 * Returns a caret position of selection end. 138 * 139 * @param oper an operator. 140 * @return int represnting index of operator's selection end. 141 */ 142 public abstract int getSelectionEnd(ComponentOperator oper); 143 144 /** 145 * Returns an array of navigation keys. 146 * 147 * @param oper an operator. 148 * @return an array on NavigationKey instances. 149 */ 150 public abstract NavigationKey[] getKeys(ComponentOperator oper); 151 152 /** 153 * Returns a timeout to sleep between text typing and caret operations. 154 * 155 * @param oper an operator. 156 * @return a Timeout instance. 157 */ 158 public abstract Timeout getBetweenTimeout(ComponentOperator oper); 159 160 /** 161 * Changes current caret position to specifyed. 162 * 163 * @param oper an operator. 164 * @param position new caret position 165 * @param preModifiers a modifiers (combination of 166 * {@code InputEvent.*_MASK} fields) pushed before caret moving (like 167 * shift during text selection). 168 */ 169 protected void changeCaretPosition(ComponentOperator oper, final int position, final int preModifiers) { 170 NavigationKey[] keys = getKeys(oper); 171 for (int i = keys.length - 1; i >= 0; i--) { 172 if (keys[i] instanceof OffsetKey) { 173 moveCaret(oper, (OffsetKey) keys[i], position, preModifiers); 174 } else { 175 moveCaret(oper, (GoAndBackKey) keys[i], position, preModifiers); 176 } 177 } 178 } 179 180 private int difference(int one, int two) { 181 if (one >= two) { 182 return one - two; 183 } else { 184 return two - one; 185 } 186 } 187 188 private void push(ComponentOperator oper, NavigationKey key, int preModifiers) { 189 DriverManager.getKeyDriver(oper). 190 pushKey(oper, key.getKeyCode(), key.getModifiers() | preModifiers, 191 oper.getTimeouts().create("ComponentOperator.PushKeyTimeout")); 192 getBetweenTimeout(oper).sleep(); 193 } 194 195 private final void moveCaret(ComponentOperator oper, GoAndBackKey key, int position, int preModifiers) { 196 int newDiff = difference(position, getCaretPosition(oper)); 197 int oldDiff = newDiff; 198 QueueTool qTool = new QueueTool(); 199 qTool.setOutput(oper.getOutput().createErrorOutput()); 200 while (key.getDirection() * (position - getCaretPosition(oper)) > 0) { 201 oldDiff = newDiff; 202 push(oper, key, preModifiers); 203 qTool.waitEmpty(); 204 newDiff = difference(position, getCaretPosition(oper)); 205 if (newDiff == oldDiff) { 206 return; 207 } 208 } 209 if (newDiff > oldDiff) { 210 push(oper, key.getBackKey(), preModifiers); 211 } 212 } 213 214 private final void moveCaret(ComponentOperator oper, OffsetKey key, int position, int preModifiers) { 215 if (gotToGo(oper, position, key.getExpectedPosition())) { 216 push(oper, key, preModifiers); 217 } 218 } 219 220 private boolean gotToGo(ComponentOperator oper, int point, int offset) { 221 return difference(point, offset) < difference(point, getCaretPosition(oper)); 222 } 223} 224