/* * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.netbeans.jemmy.drivers.text; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import org.netbeans.jemmy.CharBindingMap; import org.netbeans.jemmy.QueueTool; import org.netbeans.jemmy.Timeout; import org.netbeans.jemmy.drivers.DriverManager; import org.netbeans.jemmy.drivers.KeyDriver; import org.netbeans.jemmy.drivers.LightSupportiveDriver; import org.netbeans.jemmy.drivers.TextDriver; import org.netbeans.jemmy.operators.ComponentOperator; /** * Superclass for all TextDrivers using keyboard. * * @author Alexandre Iline(alexandre.iline@oracle.com) */ public abstract class TextKeyboardDriver extends LightSupportiveDriver implements TextDriver { /** * Constructs a TextKeyboardDriver. * * @param supported an array of supported class names */ public TextKeyboardDriver(String[] supported) { super(supported); } @Override public void changeCaretPosition(ComponentOperator oper, int position) { DriverManager.getFocusDriver(oper).giveFocus(oper); checkSupported(oper); changeCaretPosition(oper, position, 0); } @Override public void selectText(ComponentOperator oper, int startPosition, int finalPosition) { changeCaretPosition(oper, startPosition); DriverManager.getKeyDriver(oper).pressKey(oper, KeyEvent.VK_SHIFT, 0); changeCaretPosition(oper, finalPosition, InputEvent.SHIFT_MASK); DriverManager.getKeyDriver(oper).releaseKey(oper, KeyEvent.VK_SHIFT, 0); } @Override public void clearText(ComponentOperator oper) { DriverManager.getFocusDriver(oper).giveFocus(oper); checkSupported(oper); KeyDriver kdriver = DriverManager.getKeyDriver(oper); Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"); Timeout betweenTime = getBetweenTimeout(oper); while (getCaretPosition(oper) > 0) { kdriver.typeKey(oper, KeyEvent.VK_BACK_SPACE, (char) KeyEvent.VK_BACK_SPACE, 0, pushTime); betweenTime.sleep(); } while (getText(oper).length() > 0) { kdriver.pushKey(oper, KeyEvent.VK_DELETE, 0, pushTime); betweenTime.sleep(); } } @Override public void typeText(ComponentOperator oper, String text, int caretPosition) { changeCaretPosition(oper, caretPosition); KeyDriver kDriver = DriverManager.getKeyDriver(oper); CharBindingMap map = oper.getCharBindingMap(); Timeout pushTime = oper.getTimeouts().create("ComponentOperator.PushKeyTimeout"); Timeout betweenTime = getBetweenTimeout(oper); char[] crs = text.toCharArray(); for (char cr : crs) { kDriver.typeKey(oper, map.getCharKey(cr), cr, map.getCharModifiers(cr), pushTime); betweenTime.sleep(); } } @Override public void changeText(ComponentOperator oper, String text) { clearText(oper); typeText(oper, text, 0); } @Override public void enterText(ComponentOperator oper, String text) { changeText(oper, text); DriverManager.getKeyDriver(oper).pushKey(oper, KeyEvent.VK_ENTER, 0, new Timeout("", 0)); } /** * Returns operator's text. * * @param oper an operator. * @return string representing component text. */ public abstract String getText(ComponentOperator oper); /** * Returns current caret position. * * @param oper an operator. * @return int represnting current operator's caret position. */ public abstract int getCaretPosition(ComponentOperator oper); /** * Returns a caret position of selection start. * * @param oper an operator. * @return int represnting index of operator's selection start. */ public abstract int getSelectionStart(ComponentOperator oper); /** * Returns a caret position of selection end. * * @param oper an operator. * @return int represnting index of operator's selection end. */ public abstract int getSelectionEnd(ComponentOperator oper); /** * Returns an array of navigation keys. * * @param oper an operator. * @return an array on NavigationKey instances. */ public abstract NavigationKey[] getKeys(ComponentOperator oper); /** * Returns a timeout to sleep between text typing and caret operations. * * @param oper an operator. * @return a Timeout instance. */ public abstract Timeout getBetweenTimeout(ComponentOperator oper); /** * Changes current caret position to specifyed. * * @param oper an operator. * @param position new caret position * @param preModifiers a modifiers (combination of * {@code InputEvent.*_MASK} fields) pushed before caret moving (like * shift during text selection). */ protected void changeCaretPosition(ComponentOperator oper, final int position, final int preModifiers) { NavigationKey[] keys = getKeys(oper); for (int i = keys.length - 1; i >= 0; i--) { if (keys[i] instanceof OffsetKey) { moveCaret(oper, (OffsetKey) keys[i], position, preModifiers); } else { moveCaret(oper, (GoAndBackKey) keys[i], position, preModifiers); } } } private int difference(int one, int two) { if (one >= two) { return one - two; } else { return two - one; } } private void push(ComponentOperator oper, NavigationKey key, int preModifiers) { DriverManager.getKeyDriver(oper). pushKey(oper, key.getKeyCode(), key.getModifiers() | preModifiers, oper.getTimeouts().create("ComponentOperator.PushKeyTimeout")); getBetweenTimeout(oper).sleep(); } private final void moveCaret(ComponentOperator oper, GoAndBackKey key, int position, int preModifiers) { int newDiff = difference(position, getCaretPosition(oper)); int oldDiff = newDiff; QueueTool qTool = new QueueTool(); qTool.setOutput(oper.getOutput().createErrorOutput()); while (key.getDirection() * (position - getCaretPosition(oper)) > 0) { oldDiff = newDiff; push(oper, key, preModifiers); qTool.waitEmpty(); newDiff = difference(position, getCaretPosition(oper)); if (newDiff == oldDiff) { return; } } if (newDiff > oldDiff) { push(oper, key.getBackKey(), preModifiers); } } private final void moveCaret(ComponentOperator oper, OffsetKey key, int position, int preModifiers) { if (gotToGo(oper, position, key.getExpectedPosition())) { push(oper, key, preModifiers); } } private boolean gotToGo(ComponentOperator oper, int point, int offset) { return difference(point, offset) < difference(point, getCaretPosition(oper)); } }