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: ListOperator.java,v 1.11 2007/10/05 11:35:42 jskrivanek Exp $ $Revision: 1.11 $ $Date: 2007/10/05 11:35:42 $
044: *
045: */
046:
047: package org.netbeans.jemmy.operators;
048:
049: import org.netbeans.jemmy.ComponentChooser;
050: import org.netbeans.jemmy.ComponentSearcher;
051: import org.netbeans.jemmy.JemmyException;
052: import org.netbeans.jemmy.JemmyInputException;
053: import org.netbeans.jemmy.JemmyProperties;
054: import org.netbeans.jemmy.Outputable;
055: import org.netbeans.jemmy.TestOut;
056: import org.netbeans.jemmy.TimeoutExpiredException;
057:
058: import org.netbeans.jemmy.drivers.DriverManager;
059: import org.netbeans.jemmy.drivers.MultiSelListDriver;
060:
061: import java.awt.Color;
062: import java.awt.Component;
063: import java.awt.Container;
064: import java.awt.Dimension;
065: import java.awt.Point;
066: import java.awt.Rectangle;
067: import java.awt.List;
068:
069: import java.awt.event.ActionListener;
070: import java.awt.event.ItemListener;
071: import java.awt.event.KeyEvent;
072:
073: import java.util.Hashtable;
074: import java.util.Vector;
075:
076: /**
077: * <BR><BR>Timeouts used: <BR>
078: * ComponentOperator.WaitComponentTimeout - time to wait component displayed <BR>
079: * ComponentOperator.WaitComponentEnabledTimeout - time to wait component enabled <BR>.
080: *
081: * @see org.netbeans.jemmy.Timeouts
082: *
083: * @author Alexandre Iline (alexandre.iline@sun.com)
084: *
085: */
086:
087: public class ListOperator extends ComponentOperator implements
088: Outputable {
089:
090: /**
091: * Identifier for a "item" properties.
092: * @see #getDump
093: */
094: public static final String ITEM_PREFIX_DPROP = "Item";
095:
096: /**
097: * Identifier for a "selected item" property.
098: * @see #getDump
099: */
100: public static final String SELECTED_ITEM_PREFIX_DPROP = "SelectedItem";
101:
102: private TestOut output;
103: private MultiSelListDriver driver;
104:
105: /**
106: * Constructor.
107: * @param b a component
108: */
109: public ListOperator(List b) {
110: super (b);
111: driver = DriverManager.getMultiSelListDriver(getClass());
112: }
113:
114: /**
115: * Constructs a ListOperator object.
116: * @param cont a container
117: * @param chooser a component chooser specifying searching criteria.
118: * @param index an index between appropriate ones.
119: */
120: public ListOperator(ContainerOperator cont,
121: ComponentChooser chooser, int index) {
122: this ((List) cont.waitSubComponent(new ListFinder(chooser),
123: index));
124: copyEnvironment(cont);
125: }
126:
127: /**
128: * Constructs a ListOperator object.
129: * @param cont a container
130: * @param chooser a component chooser specifying searching criteria.
131: */
132: public ListOperator(ContainerOperator cont, ComponentChooser chooser) {
133: this (cont, chooser, 0);
134: }
135:
136: /**
137: * Constructor.
138: * Waits item text first.
139: * Uses cont's timeout and output for waiting and to init operator.
140: * @param cont a container
141: * @param text Text of item which is currently selected.
142: * @param itemIndex Item index.
143: * @param index Ordinal component index.
144: * @throws TimeoutExpiredException
145: */
146: public ListOperator(ContainerOperator cont, String text,
147: int itemIndex, int index) {
148: this ((List) waitComponent(cont, new ListByItemFinder(text,
149: itemIndex, cont.getComparator()), index));
150: copyEnvironment(cont);
151: }
152:
153: /**
154: * Constructor.
155: * Waits component by selected item text first.
156: * Uses cont's timeout and output for waiting and to init operator.
157: * @param cont a container
158: * @param text Text of item which is currently selected.
159: * @param index Ordinal component index.
160: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
161: * @throws TimeoutExpiredException
162: */
163: public ListOperator(ContainerOperator cont, String text, int index) {
164: this (cont, text, -1, index);
165: }
166:
167: /**
168: * Constructor.
169: * Waits component in container first.
170: * Uses cont's timeout and output for waiting and to init operator.
171: * @param cont a container
172: * @param text Text of item which is currently selected.
173: * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
174: * @throws TimeoutExpiredException
175: */
176: public ListOperator(ContainerOperator cont, String text) {
177: this (cont, text, 0);
178: }
179:
180: /**
181: * Constructor.
182: * Waits component in container first.
183: * Uses cont's timeout and output for waiting and to init operator.
184: * @param cont a container
185: * @param index Ordinal component index.
186: * @throws TimeoutExpiredException
187: */
188: public ListOperator(ContainerOperator cont, int index) {
189: this ((List) waitComponent(cont, new ListFinder(), index));
190: copyEnvironment(cont);
191: }
192:
193: /**
194: * Constructor.
195: * Waits component in container first.
196: * Uses cont's timeout and output for waiting and to init operator.
197: * @param cont a container
198: * @throws TimeoutExpiredException
199: */
200: public ListOperator(ContainerOperator cont) {
201: this (cont, 0);
202: }
203:
204: /**
205: * Searches List in container.
206: * @param cont Container to search component in.
207: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
208: * @param index Ordinal component index.
209: * @return List instance or null if component was not found.
210: */
211: public static List findList(Container cont,
212: ComponentChooser chooser, int index) {
213: return ((List) findComponent(cont, new ListFinder(chooser),
214: index));
215: }
216:
217: /**
218: * Searches 0'th List in container.
219: * @param cont Container to search component in.
220: * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
221: * @return List instance or null if component was not found.
222: */
223: public static List findList(Container cont, ComponentChooser chooser) {
224: return (findList(cont, chooser, 0));
225: }
226:
227: public void setOutput(TestOut output) {
228: super .setOutput(output.createErrorOutput());
229: this .output = output;
230: }
231:
232: public TestOut getOutput() {
233: return (output);
234: }
235:
236: public void copyEnvironment(Operator anotherOperator) {
237: super .copyEnvironment(anotherOperator);
238: driver = (MultiSelListDriver) DriverManager.getDriver(
239: DriverManager.MULTISELLIST_DRIVER_ID, getClass(),
240: anotherOperator.getProperties());
241: }
242:
243: private int findItemIndex(String item, StringComparator comparator,
244: int index) {
245: int count = 0;
246: for (int i = 0; i < getItemCount(); i++) {
247: if (comparator.equals(getItem(i), item)) {
248: if (count == index) {
249: return (i);
250: } else {
251: count++;
252: }
253: }
254: }
255: return (-1);
256: }
257:
258: /**
259: * Searches an item index.
260: * @param item item text.
261: * @param index an ordinal index between appropriate ones.
262: * @return an index.
263: */
264: public int findItemIndex(String item, int index) {
265: return (findItemIndex(item, getComparator(), index));
266: }
267:
268: /**
269: * Searches an item index.
270: * @param item item text.
271: * @return an index.
272: */
273: public int findItemIndex(String item) {
274: return (findItemIndex(item, 0));
275: }
276:
277: private void selectItem(String item, StringComparator comparator,
278: int index) {
279: selectItem(findItemIndex(item, comparator, index));
280: }
281:
282: /**
283: * Selects an item.
284: * @param item item text.
285: * @param index an ordinal index between appropriate ones.
286: */
287: public void selectItem(String item, int index) {
288: selectItem(item, getComparator(), index);
289: }
290:
291: /**
292: * Selects an item.
293: * @param item item text.
294: */
295: public void selectItem(String item) {
296: selectItem(item, 0);
297: }
298:
299: /**
300: * Selects an item.
301: * @param index an item index.
302: */
303: public void selectItem(int index) {
304: output.printLine("Select " + Integer.toString(index)
305: + "`th item in list\n : " + toStringSource());
306: output.printGolden("Select " + Integer.toString(index)
307: + "`th item in list");
308: driver.selectItem(this , index);
309: if (getVerification()) {
310: waitItemSelection(index, true);
311: }
312: }
313:
314: /**
315: * Selects some items.
316: * @param from start selection index.
317: * @param to end selection index.
318: */
319: public void selectItems(int from, int to) {
320: output.printLine("Select items from " + Integer.toString(from)
321: + "`th to " + Integer.toString(from)
322: + "'th in list\n : " + toStringSource());
323: output.printGolden("Select items from "
324: + Integer.toString(from) + "`th to "
325: + Integer.toString(from) + "'th");
326: driver.selectItems(this , new int[] { from, to });
327: if (getVerification()) {
328: waitItemsSelection(from, to, true);
329: }
330: }
331:
332: /**
333: * Waits for items to be selected.
334: * @param from Start selection inex
335: * @param to End selection inex
336: * @param selected Selected (true) or unselected (false).
337: */
338: public void waitItemsSelection(final int from, final int to,
339: final boolean selected) {
340: getOutput().printLine(
341: "Wait items to be " + (selected ? "" : "un")
342: + "selected in component \n : "
343: + toStringSource());
344: getOutput().printGolden(
345: "Wait items to be " + (selected ? "" : "un")
346: + "selected");
347: waitState(new ComponentChooser() {
348: public boolean checkComponent(Component comp) {
349: int[] indices = getSelectedIndexes();
350: for (int i = 0; i < indices.length; i++) {
351: if (indices[i] < from || indices[i] > to) {
352: return (false);
353: }
354: }
355: return (true);
356: }
357:
358: public String getDescription() {
359: return ("Items has been " + (selected ? "" : "un") + "selected");
360: }
361: });
362: }
363:
364: /**
365: * Waits for item to be selected.
366: * @param itemIndex an item index to be selected.
367: * @param selected Selected (true) or unselected (false).
368: */
369: public void waitItemSelection(final int itemIndex,
370: final boolean selected) {
371: waitItemsSelection(itemIndex, itemIndex, selected);
372: }
373:
374: public Hashtable getDump() {
375: Hashtable result = super .getDump();
376: addToDump(result, ITEM_PREFIX_DPROP, ((List) getSource())
377: .getItems());
378: addToDump(result, SELECTED_ITEM_PREFIX_DPROP,
379: ((List) getSource()).getSelectedItems());
380: return (result);
381: }
382:
383: ////////////////////////////////////////////////////////
384: //Mapping //
385:
386: /**Maps <code>List.addActionListener(ActionListener)</code> through queue*/
387: public void addActionListener(final ActionListener actionListener) {
388: runMapping(new MapVoidAction("addActionListener") {
389: public void map() {
390: ((List) getSource()).addActionListener(actionListener);
391: }
392: });
393: }
394:
395: /**Maps <code>List.addItemListener(ItemListener)</code> through queue*/
396: public void addItemListener(final ItemListener itemListener) {
397: runMapping(new MapVoidAction("addItemListener") {
398: public void map() {
399: ((List) getSource()).addItemListener(itemListener);
400: }
401: });
402: }
403:
404: /**Maps <code>List.deselect(int)</code> through queue*/
405: public void deselect(final int i) {
406: runMapping(new MapVoidAction("deselect") {
407: public void map() {
408: ((List) getSource()).deselect(i);
409: }
410: });
411: }
412:
413: /**Maps <code>List.getItem(int)</code> through queue*/
414: public String getItem(final int i) {
415: return ((String) runMapping(new MapAction("getItem") {
416: public Object map() {
417: return (((List) getSource()).getItem(i));
418: }
419: }));
420: }
421:
422: /**Maps <code>List.getItemCount()</code> through queue*/
423: public int getItemCount() {
424: return (runMapping(new MapIntegerAction("getItemCount") {
425: public int map() {
426: return (((List) getSource()).getItemCount());
427: }
428: }));
429: }
430:
431: /**Maps <code>List.getItems()</code> through queue*/
432: public String[] getItems() {
433: return ((String[]) runMapping(new MapAction("getItems") {
434: public Object map() {
435: return (((List) getSource()).getItems());
436: }
437: }));
438: }
439:
440: /**Maps <code>List.getMinimumSize(int)</code> through queue*/
441: public Dimension getMinimumSize(final int i) {
442: return ((Dimension) runMapping(new MapAction("getMinimumSize") {
443: public Object map() {
444: return (((List) getSource()).getMinimumSize(i));
445: }
446: }));
447: }
448:
449: /**Maps <code>List.getPreferredSize(int)</code> through queue*/
450: public Dimension getPreferredSize(final int i) {
451: return ((Dimension) runMapping(new MapAction("getPreferredSize") {
452: public Object map() {
453: return (((List) getSource()).getPreferredSize(i));
454: }
455: }));
456: }
457:
458: /**Maps <code>List.getRows()</code> through queue*/
459: public int getRows() {
460: return (runMapping(new MapIntegerAction("getRows") {
461: public int map() {
462: return (((List) getSource()).getRows());
463: }
464: }));
465: }
466:
467: /**Maps <code>List.getSelectedIndex()</code> through queue*/
468: public int getSelectedIndex() {
469: return (runMapping(new MapIntegerAction("getSelectedIndex") {
470: public int map() {
471: return (((List) getSource()).getSelectedIndex());
472: }
473: }));
474: }
475:
476: /**Maps <code>List.getSelectedIndexes()</code> through queue*/
477: public int[] getSelectedIndexes() {
478: return ((int[]) runMapping(new MapAction("getSelectedIndexes") {
479: public Object map() {
480: return (((List) getSource()).getSelectedIndexes());
481: }
482: }));
483: }
484:
485: /**Maps <code>List.getSelectedItem()</code> through queue*/
486: public String getSelectedItem() {
487: return ((String) runMapping(new MapAction("getSelectedItem") {
488: public Object map() {
489: return (((List) getSource()).getSelectedItem());
490: }
491: }));
492: }
493:
494: /**Maps <code>List.getSelectedItems()</code> through queue*/
495: public String[] getSelectedItems() {
496: return ((String[]) runMapping(new MapAction("getSelectedItems") {
497: public Object map() {
498: return (((List) getSource()).getSelectedItems());
499: }
500: }));
501: }
502:
503: /**Maps <code>List.getSelectedObjects()</code> through queue*/
504: public Object[] getSelectedObjects() {
505: return ((Object[]) runMapping(new MapAction(
506: "getSelectedObjects") {
507: public Object map() {
508: return (((List) getSource()).getSelectedObjects());
509: }
510: }));
511: }
512:
513: /**Maps <code>List.getVisibleIndex()</code> through queue*/
514: public int getVisibleIndex() {
515: return (runMapping(new MapIntegerAction("getVisibleIndex") {
516: public int map() {
517: return (((List) getSource()).getVisibleIndex());
518: }
519: }));
520: }
521:
522: /**Maps <code>List.isIndexSelected(int)</code> through queue*/
523: public boolean isIndexSelected(final int i) {
524: return (runMapping(new MapBooleanAction("isIndexSelected") {
525: public boolean map() {
526: return (((List) getSource()).isIndexSelected(i));
527: }
528: }));
529: }
530:
531: /**Maps <code>List.isMultipleMode()</code> through queue*/
532: public boolean isMultipleMode() {
533: return (runMapping(new MapBooleanAction("isMultipleMode") {
534: public boolean map() {
535: return (((List) getSource()).isMultipleMode());
536: }
537: }));
538: }
539:
540: /**Maps <code>List.makeVisible(int)</code> through queue*/
541: public void makeVisible(final int i) {
542: runMapping(new MapVoidAction("makeVisible") {
543: public void map() {
544: ((List) getSource()).makeVisible(i);
545: }
546: });
547: }
548:
549: /**Maps <code>List.remove(int)</code> through queue*/
550: public void remove(final int i) {
551: runMapping(new MapVoidAction("remove") {
552: public void map() {
553: ((List) getSource()).remove(i);
554: }
555: });
556: }
557:
558: /**Maps <code>List.remove(String)</code> through queue*/
559: public void remove(final String string) {
560: runMapping(new MapVoidAction("remove") {
561: public void map() {
562: ((List) getSource()).remove(string);
563: }
564: });
565: }
566:
567: /**Maps <code>List.removeActionListener(ActionListener)</code> through queue*/
568: public void removeActionListener(final ActionListener actionListener) {
569: runMapping(new MapVoidAction("removeActionListener") {
570: public void map() {
571: ((List) getSource())
572: .removeActionListener(actionListener);
573: }
574: });
575: }
576:
577: /**Maps <code>List.removeAll()</code> through queue*/
578: public void removeAll() {
579: runMapping(new MapVoidAction("removeAll") {
580: public void map() {
581: ((List) getSource()).removeAll();
582: }
583: });
584: }
585:
586: /**Maps <code>List.removeItemListener(ItemListener)</code> through queue*/
587: public void removeItemListener(final ItemListener itemListener) {
588: runMapping(new MapVoidAction("removeItemListener") {
589: public void map() {
590: ((List) getSource()).removeItemListener(itemListener);
591: }
592: });
593: }
594:
595: /**Maps <code>List.replaceItem(String, int)</code> through queue*/
596: public void replaceItem(final String string, final int i) {
597: runMapping(new MapVoidAction("replaceItem") {
598: public void map() {
599: ((List) getSource()).replaceItem(string, i);
600: }
601: });
602: }
603:
604: /**Maps <code>List.select(int)</code> through queue*/
605: public void select(final int i) {
606: runMapping(new MapVoidAction("select") {
607: public void map() {
608: ((List) getSource()).select(i);
609: }
610: });
611: }
612:
613: /**Maps <code>List.setMultipleMode(boolean)</code> through queue*/
614: public void setMultipleMode(final boolean b) {
615: runMapping(new MapVoidAction("setMultipleMode") {
616: public void map() {
617: ((List) getSource()).setMultipleMode(b);
618: }
619: });
620: }
621:
622: //End of mapping //
623: ////////////////////////////////////////////////////////
624:
625: /**
626: * Allows to find component by item text.
627: */
628: public static class ListByItemFinder implements ComponentChooser {
629: String label;
630: int itemIndex;
631: StringComparator comparator;
632:
633: /**
634: * Constructs ListByItemFinder.
635: * @param lb a text pattern
636: * @param ii item index to check. If equal to -1, selected item is checked.
637: * @param comparator specifies string comparision algorithm.
638: */
639: public ListByItemFinder(String lb, int ii,
640: StringComparator comparator) {
641: label = lb;
642: itemIndex = ii;
643: this .comparator = comparator;
644: }
645:
646: /**
647: * Constructs ListByItemFinder.
648: * @param lb a text pattern
649: * @param ii item index to check. If equal to -1, selected item is checked.
650: */
651: public ListByItemFinder(String lb, int ii) {
652: this (lb, ii, Operator.getDefaultStringComparator());
653: }
654:
655: public boolean checkComponent(Component comp) {
656: if (comp instanceof List) {
657: if (label == null) {
658: return (true);
659: }
660: if (((List) comp).getItemCount() > itemIndex) {
661: int ii = itemIndex;
662: if (ii == -1) {
663: ii = ((List) comp).getSelectedIndex();
664: if (ii == -1) {
665: return (false);
666: }
667: }
668: return (comparator.equals(
669: ((List) comp).getItem(ii), label));
670: }
671: }
672: return (false);
673: }
674:
675: public String getDescription() {
676: return ("List with text \"" + label + "\" in "
677: + (new Integer(itemIndex)).toString() + "'th item");
678: }
679: }
680:
681: /**
682: * Checks component type.
683: */
684: public static class ListFinder extends Finder {
685: /**
686: * Constructs ListFinder.
687: * @param sf other searching criteria.
688: */
689: public ListFinder(ComponentChooser sf) {
690: super (List.class, sf);
691: }
692:
693: /**
694: * Constructs ListFinder.
695: */
696: public ListFinder() {
697: super (List.class);
698: }
699: }
700: }
|