001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s): Alexandre Iline.
025: *
026: * The Original Software is the Jemmy library.
027: * The Initial Developer of the Original Software is Alexandre Iline.
028: * All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: *
041: *
042: *
043: * $Id: ButtonOperator.java,v 1.8 2007/10/05 11:35:51 jskrivanek Exp $ $Revision: 1.8 $ $Date: 2007/10/05 11:35:51 $
044: *
045: */
046:
047: package org.netbeans.jemmy.operators;
048:
049: import org.netbeans.jemmy.Action;
050: import org.netbeans.jemmy.ComponentChooser;
051: import org.netbeans.jemmy.ComponentSearcher;
052: import org.netbeans.jemmy.JemmyException;
053: import org.netbeans.jemmy.JemmyProperties;
054: import org.netbeans.jemmy.Outputable;
055: import org.netbeans.jemmy.TestOut;
056: import org.netbeans.jemmy.Timeoutable;
057: import org.netbeans.jemmy.TimeoutExpiredException;
058: import org.netbeans.jemmy.Timeouts;
059:
060: import org.netbeans.jemmy.drivers.ButtonDriver;
061: import org.netbeans.jemmy.drivers.DriverManager;
062:
063: import java.awt.Button;
064: import java.awt.Component;
065: import java.awt.Container;
066:
067: import java.awt.event.ActionListener;
068:
069: import java.util.Hashtable;
070:
071: /**
072: *
073: * <BR><BR>Timeouts used: <BR>
074: * ButtonOperator.PushButtonTimeout - time between button pressing and releasing<BR>
075: * ComponentOperator.WaitComponentTimeout - time to wait button displayed <BR>
076: * ComponentOperator.WaitComponentEnabledTimeout - time to wait button enabled <BR>.
077: *
078: * @see org.netbeans.jemmy.Timeouts
079: *
080: * @author Alexandre Iline (alexandre.iline@sun.com)
081: *
082: */
083:
084: public class ButtonOperator extends ComponentOperator implements
085: Timeoutable, Outputable {
086:
087: /**
088: * Identifier for a label property.
089: * @see #getDump
090: */
091: public static final String TEXT_DPROP = "Label";
092:
093: private final static long PUSH_BUTTON_TIMEOUT = 0;
094:
095: private Timeouts timeouts;
096: private TestOut output;
097:
098: ButtonDriver driver;
099:
100: /**
101: * Constructor.
102: * @param b The <code>java.awt.Button</code> managed by
103: * this instance.
104: */
105: public ButtonOperator(Button b) {
106: super (b);
107: driver = DriverManager.getButtonDriver(getClass());
108: }
109:
110: /**
111: * Constructs a ButtonOperator object.
112: * @param cont container
113: * @param chooser a component chooser specifying searching criteria.
114: * @param index an index between appropriate ones.
115: */
116: public ButtonOperator(ContainerOperator cont,
117: ComponentChooser chooser, int index) {
118: this ((Button) cont.waitSubComponent(new ButtonFinder(chooser),
119: index));
120: copyEnvironment(cont);
121: }
122:
123: /**
124: * Constructs a ButtonOperator object.
125: * @param cont container
126: * @param chooser a component chooser specifying searching criteria.
127: */
128: public ButtonOperator(ContainerOperator cont,
129: ComponentChooser chooser) {
130: this (cont, chooser, 0);
131: }
132:
133: /**
134: * Constructor.
135: * Waits for a component in a container to show. The component is
136: * identified as the <code>index+1</code>'th
137: * <code>java.awt.Button</code> that shows, lies below
138: * the container in the display containment hierarchy,
139: * and that has the desired text. Uses cont's timeout and output
140: * for waiting and to init this operator.
141: * @param cont The operator for a container containing the sought for button.
142: * @param text Button text.
143: * @param index Ordinal component index. The first component has <code>index</code> 0.
144: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
145: * @throws TimeoutExpiredException
146: */
147: public ButtonOperator(ContainerOperator cont, String text, int index) {
148: this ((Button) waitComponent(cont, new ButtonByLabelFinder(text,
149: cont.getComparator()), index));
150: copyEnvironment(cont);
151: }
152:
153: /**
154: * Constructor.
155: * Waits for a component in a container to show. The component is
156: * identified as the first
157: * <code>java.awt.Button</code> that shows, lies below
158: * the container in the display containment hierarchy,
159: * and that has the desired text. Uses cont's timeout and output
160: * for waiting and to init this operator.
161: * @param cont The operator for a container containing the sought for button.
162: * @param text Button text.
163: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
164: * @throws TimeoutExpiredException
165: */
166: public ButtonOperator(ContainerOperator cont, String text) {
167: this (cont, text, 0);
168: }
169:
170: /**
171: * Constructor.
172: * Waits component in container first.
173: * Uses cont's timeout and output for waiting and to init operator.
174: * @param cont The operator for a container containing the sought for button.
175: * @param index Ordinal component index.
176: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
177: * @throws TimeoutExpiredException
178: */
179: public ButtonOperator(ContainerOperator cont, int index) {
180: this ((Button) waitComponent(cont, new ButtonFinder(), index));
181: copyEnvironment(cont);
182: }
183:
184: /**
185: * Constructor.
186: * Waits component in container first.
187: * Uses cont's timeout and output for waiting and to init operator.
188: * @param cont The operator for a container containing the sought for button.
189: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
190: * @throws TimeoutExpiredException
191: */
192: public ButtonOperator(ContainerOperator cont) {
193: this (cont, 0);
194: }
195:
196: /**
197: * Searches Button in a container.
198: * @param cont Container in which to search for the component. The container
199: * lies above the component in the display containment hierarchy. The containment
200: * need not be direct.
201: * @param chooser org.netbeans.jemmy.ComponentChooser implementation, defining and
202: * applying search criteria.
203: * @param index Ordinal component index. The first <code>index</code> is 0.
204: * @return Button instance or null if component was not found.
205: */
206: public static Button findButton(Container cont,
207: ComponentChooser chooser, int index) {
208: return ((Button) findComponent(cont, new ButtonFinder(chooser),
209: index));
210: }
211:
212: /**
213: * Searches for the first Button in a container.
214: * @param cont Container in which to search for the component. The container
215: * lies above the component in the display containment hierarchy. The containment
216: * need not be direct.
217: * @param chooser org.netbeans.jemmy.ComponentChooser implementation, defining and
218: * applying search criteria.
219: * @return Button instance or null if component was not found.
220: */
221: public static Button findButton(Container cont,
222: ComponentChooser chooser) {
223: return (findButton(cont, chooser, 0));
224: }
225:
226: /**
227: * Searches Button by text.
228: * @param cont Container to search component in.
229: * @param text Button text. If null, contents is not checked.
230: * @param ce Compare text exactly.
231: * @param ccs Compare text case sensitively.
232: * @param index Ordinal component index.
233: * @return Button instance or null if component was not found.
234: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
235: */
236: public static Button findButton(Container cont, String text,
237: boolean ce, boolean ccs, int index) {
238: return (findButton(cont, new ButtonByLabelFinder(text,
239: new DefaultStringComparator(ce, ccs)), index));
240: }
241:
242: /**
243: * Searches Button by text.
244: * @param cont Container to search component in.
245: * @param text Button text. If null, contents is not checked.
246: * @param ce Compare text exactly.
247: * @param ccs Compare text case sensitively.
248: * @return Button instance or null if component was not found.
249: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
250: */
251: public static Button findButton(Container cont, String text,
252: boolean ce, boolean ccs) {
253: return (findButton(cont, text, ce, ccs, 0));
254: }
255:
256: /**
257: * Waits Button in container.
258: * @param cont Container to search component in.
259: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
260: * @param index Ordinal component index.
261: * @return Button instance.
262: * @throws TimeoutExpiredException
263: */
264: public static Button waitButton(Container cont,
265: ComponentChooser chooser, int index) {
266: return ((Button) waitComponent(cont, new ButtonFinder(chooser),
267: index));
268: }
269:
270: /**
271: * Waits 0'th Button in container.
272: * @param cont Container to search component in.
273: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
274: * @return Button instance.
275: * @throws TimeoutExpiredException
276: */
277: public static Button waitButton(Container cont,
278: ComponentChooser chooser) {
279: return (waitButton(cont, chooser, 0));
280: }
281:
282: /**
283: * Waits Button by text.
284: * @param cont Container to search component in.
285: * @param text Button text. If null, contents is not checked.
286: * @param ce Compare text exactly.
287: * @param ccs Compare text case sensitively.
288: * @param index Ordinal component index.
289: * @return Button instance.
290: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
291: * @throws TimeoutExpiredException
292: */
293: public static Button waitButton(Container cont, String text,
294: boolean ce, boolean ccs, int index) {
295: return (waitButton(cont, new ButtonByLabelFinder(text,
296: new DefaultStringComparator(ce, ccs)), index));
297: }
298:
299: /**
300: * Waits Button by text.
301: * @param cont Container to search component in.
302: * @param text Button text. If null, contents is not checked.
303: * @param ce Compare text exactly.
304: * @param ccs Compare text case sensitively.
305: * @return Button instance.
306: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
307: * @throws TimeoutExpiredException
308: */
309: public static Button waitButton(Container cont, String text,
310: boolean ce, boolean ccs) {
311: return (waitButton(cont, text, ce, ccs, 0));
312: }
313:
314: static {
315: Timeouts.initDefault("ButtonOperator.PushButtonTimeout",
316: PUSH_BUTTON_TIMEOUT);
317: }
318:
319: public void setTimeouts(Timeouts timeouts) {
320: super .setTimeouts(timeouts);
321: this .timeouts = timeouts;
322: }
323:
324: public Timeouts getTimeouts() {
325: return (timeouts);
326: }
327:
328: public void setOutput(TestOut out) {
329: output = out;
330: super .setOutput(output.createErrorOutput());
331: }
332:
333: public TestOut getOutput() {
334: return (output);
335: }
336:
337: public void copyEnvironment(Operator anotherOperator) {
338: super .copyEnvironment(anotherOperator);
339: driver = (ButtonDriver) DriverManager.getDriver(
340: DriverManager.BUTTON_DRIVER_ID, getClass(),
341: anotherOperator.getProperties());
342: }
343:
344: /**
345: * Pushes the button by mouse click.
346: * @throws TimeoutExpiredException
347: */
348: public void push() {
349: output.printLine("Push button\n :" + toStringSource());
350: output.printGolden("Push button");
351: driver.push(this );
352: }
353:
354: /**
355: * Runs <code>push()</code> method in a separate thread.
356: */
357: public void pushNoBlock() {
358: produceNoBlocking(new NoBlockingAction("Button pushing") {
359: public Object doAction(Object param) {
360: push();
361: return (null);
362: }
363: });
364: }
365:
366: /**
367: * Press the button by mouse.
368: * @throws TimeoutExpiredException
369: */
370: public void press() {
371: output.printLine("Press button\n :" + toStringSource());
372: output.printGolden("Press button");
373: driver.press(this );
374: }
375:
376: /**
377: * Releases the button by mouse.
378: * @throws TimeoutExpiredException
379: */
380: public void release() {
381: output.printLine("Release button\n :" + toStringSource());
382: output.printGolden("Release button");
383: driver.press(this );
384: }
385:
386: /**
387: * Returns information about component.
388: */
389: public Hashtable getDump() {
390: Hashtable result = super .getDump();
391: if (((Button) getSource()).getLabel() != null) {
392: result.put(TEXT_DPROP, ((Button) getSource()).getLabel());
393: }
394: return (result);
395: }
396:
397: ////////////////////////////////////////////////////////
398: //Mapping //
399:
400: /**Maps <code>Button.addActionListener(ActionListener)</code> through queue*/
401: public void addActionListener(final ActionListener actionListener) {
402: runMapping(new MapVoidAction("addActionListener") {
403: public void map() {
404: ((Button) getSource())
405: .addActionListener(actionListener);
406: }
407: });
408: }
409:
410: /**Maps <code>Button.getActionCommand()</code> through queue*/
411: public String getActionCommand() {
412: return ((String) runMapping(new MapAction("getActionCommand") {
413: public Object map() {
414: return (((Button) getSource()).getActionCommand());
415: }
416: }));
417: }
418:
419: /**Maps <code>Button.getLabel()</code> through queue*/
420: public String getLabel() {
421: return ((String) runMapping(new MapAction("getLabel") {
422: public Object map() {
423: return (((Button) getSource()).getLabel());
424: }
425: }));
426: }
427:
428: /**Maps <code>Button.removeActionListener(ActionListener)</code> through queue*/
429: public void removeActionListener(final ActionListener actionListener) {
430: runMapping(new MapVoidAction("removeActionListener") {
431: public void map() {
432: ((Button) getSource())
433: .removeActionListener(actionListener);
434: }
435: });
436: }
437:
438: /**Maps <code>Button.setActionCommand(String)</code> through queue*/
439: public void setActionCommand(final String string) {
440: runMapping(new MapVoidAction("setActionCommand") {
441: public void map() {
442: ((Button) getSource()).setActionCommand(string);
443: }
444: });
445: }
446:
447: /**Maps <code>Button.setLabel(String)</code> through queue*/
448: public void setLabel(final String string) {
449: runMapping(new MapVoidAction("setLabel") {
450: public void map() {
451: ((Button) getSource()).setLabel(string);
452: }
453: });
454: }
455:
456: //End of mapping //
457: ////////////////////////////////////////////////////////
458:
459: /**
460: * Allows to find component by label.
461: */
462: public static class ButtonByLabelFinder implements ComponentChooser {
463: String label;
464: StringComparator comparator;
465:
466: /**
467: * Constructs ButtonByLabelFinder.
468: * @param lb a text pattern
469: * @param comparator specifies string comparision algorithm.
470: */
471: public ButtonByLabelFinder(String lb,
472: StringComparator comparator) {
473: label = lb;
474: this .comparator = comparator;
475: }
476:
477: /**
478: * Constructs ButtonByLabelFinder.
479: * @param lb a text pattern
480: */
481: public ButtonByLabelFinder(String lb) {
482: this (lb, Operator.getDefaultStringComparator());
483: }
484:
485: public boolean checkComponent(Component comp) {
486: if (comp instanceof Button) {
487: if (((Button) comp).getLabel() != null) {
488: return (comparator.equals(((Button) comp)
489: .getLabel(), label));
490: }
491: }
492: return (false);
493: }
494:
495: public String getDescription() {
496: return ("Button with label \"" + label + "\"");
497: }
498: }
499:
500: /**
501: * Checks component type.
502: */
503: public static class ButtonFinder extends Finder {
504: /**
505: * Constructs AbstractButtonFinder.
506: * @param sf other searching criteria.
507: */
508: public ButtonFinder(ComponentChooser sf) {
509: super (Button.class, sf);
510: }
511:
512: /**
513: * Constructs AbstractButtonFinder.
514: */
515: public ButtonFinder() {
516: super (Button.class);
517: }
518: }
519: }
|