JTextComponentOperator.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.operators;
24
25import java.awt.Color;
26import java.awt.Component;
27import java.awt.Container;
28import java.awt.Dimension;
29import java.awt.Insets;
30import java.awt.Point;
31import java.awt.Rectangle;
32import java.io.IOException;
33import java.io.Reader;
34import java.io.Writer;
35import java.util.Hashtable;
36
37import javax.swing.JScrollPane;
38import javax.swing.event.CaretListener;
39import javax.swing.plaf.TextUI;
40import javax.swing.text.BadLocationException;
41import javax.swing.text.Caret;
42import javax.swing.text.Document;
43import javax.swing.text.Highlighter;
44import javax.swing.text.JTextComponent;
45import javax.swing.text.Keymap;
46
47import org.netbeans.jemmy.Action;
48import org.netbeans.jemmy.ComponentChooser;
49import org.netbeans.jemmy.ComponentSearcher;
50import org.netbeans.jemmy.JemmyException;
51import org.netbeans.jemmy.JemmyInputException;
52import org.netbeans.jemmy.Outputable;
53import org.netbeans.jemmy.TestOut;
54import org.netbeans.jemmy.TimeoutExpiredException;
55import org.netbeans.jemmy.Timeoutable;
56import org.netbeans.jemmy.Timeouts;
57import org.netbeans.jemmy.drivers.DriverManager;
58import org.netbeans.jemmy.drivers.TextDriver;
59import org.netbeans.jemmy.util.EmptyVisualizer;
60
61/**
62 *
63 * Class provides basic functions to operate with JTextComponent (selection,
64 * typing, deleting)
65 *
66 * <BR><BR>Timeouts used: <BR>
67 * JTextComponentOperator.PushKeyTimeout - time between key pressing and
68 * releasing during text typing <BR>
69 * JTextComponentOperator.BetweenKeysTimeout - time to sleep between two chars
70 * typing <BR>
71 * JTextComponentOperator.ChangeCaretPositionTimeout - maximum time to chenge
72 * caret position <BR>
73 * JTextComponentOperator.TypeTextTimeout - maximum time to type text <BR>
74 * ComponentOperator.WaitComponentTimeout - time to wait component displayed
75 * <BR>
76 * ComponentOperator.WaitFocusTimeout - time to wait component focus <BR>
77 * ComponentOperator.WaitStateTimeout - time to wait for text <BR>
78 * JScrollBarOperator.OneScrollClickTimeout - time for one scroll click <BR>
79 * JScrollBarOperator.WholeScrollTimeout - time for the whole scrolling <BR>.
80 *
81 * @see org.netbeans.jemmy.Timeouts
82 *
83 * @author Alexandre Iline (alexandre.iline@oracle.com)
84 */
85public class JTextComponentOperator extends JComponentOperator
86        implements Timeoutable, Outputable {
87
88    /**
89     * Identifier for a "text" property.
90     *
91     * @see #getDump
92     */
93    public static final String TEXT_DPROP = "Text";
94
95    /**
96     * Identifier for a "selected text" property.
97     *
98     * @see #getDump
99     */
100    public static final String SELECTED_TEXT_DPROP = "Selected text";
101
102    /**
103     * Identifier for a "editable" property.
104     *
105     * @see #getDump
106     */
107    public static final String IS_EDITABLE_DPROP = "Editable";
108
109    private final static long PUSH_KEY_TIMEOUT = 0;
110    private final static long BETWEEN_KEYS_TIMEOUT = 0;
111    private final static long CHANGE_CARET_POSITION_TIMEOUT = 60000;
112    private final static long TYPE_TEXT_TIMEOUT = 60000;
113
114    private Timeouts timeouts;
115    private TestOut output;
116
117    /**
118     * Notifies what modifiers are pressed.
119     *
120     * @deprecated All text operations are performed by TextDriver regitered for
121     * this operator type.
122     */
123    @Deprecated
124    protected int modifiersPressed = 0;
125
126    private TextDriver driver;
127
128    /**
129     * Constructor.
130     *
131     * @param b Component to operate with.
132     */
133    public JTextComponentOperator(JTextComponent b) {
134        super(b);
135        driver = DriverManager.getTextDriver(getClass());
136    }
137
138    /**
139     * Constructs a JTextComponentOperator object.
140     *
141     * @param cont a container
142     * @param chooser a component chooser specifying searching criteria.
143     * @param index an index between appropriate ones.
144     */
145    public JTextComponentOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
146        this((JTextComponent) cont.
147                waitSubComponent(new JTextComponentFinder(chooser),
148                        index));
149        copyEnvironment(cont);
150    }
151
152    /**
153     * Constructs a JTextComponentOperator object.
154     *
155     * @param cont a container
156     * @param chooser a component chooser specifying searching criteria.
157     */
158    public JTextComponentOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
159        this(cont, chooser, 0);
160    }
161
162    /**
163     * Constructor. Waits component in container first. Uses cont's timeout and
164     * output for waiting and to init operator.
165     *
166     * @param cont a container
167     * @param text Button text.
168     * @param index Ordinal component index.
169     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
170     * @throws TimeoutExpiredException
171     */
172    public JTextComponentOperator(ContainerOperator<?> cont, String text, int index) {
173        this((JTextComponent) waitComponent(cont,
174                new JTextComponentByTextFinder(text,
175                        cont.getComparator()),
176                index));
177        copyEnvironment(cont);
178    }
179
180    /**
181     * Constructor. Waits component in container first. Uses cont's timeout and
182     * output for waiting and to init operator.
183     *
184     * @param cont a container
185     * @param text Button text.
186     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
187     * @throws TimeoutExpiredException
188     */
189    public JTextComponentOperator(ContainerOperator<?> cont, String text) {
190        this(cont, text, 0);
191    }
192
193    /**
194     * Constructor. Waits component in container first. Uses cont's timeout and
195     * output for waiting and to init operator.
196     *
197     * @param cont a container
198     * @param index Ordinal component index.
199     * @throws TimeoutExpiredException
200     */
201    public JTextComponentOperator(ContainerOperator<?> cont, int index) {
202        this((JTextComponent) waitComponent(cont,
203                new JTextComponentFinder(),
204                index));
205        copyEnvironment(cont);
206    }
207
208    /**
209     * Constructor. Waits component in container first. Uses cont's timeout and
210     * output for waiting and to init operator.
211     *
212     * @param cont a container
213     * @throws TimeoutExpiredException
214     */
215    public JTextComponentOperator(ContainerOperator<?> cont) {
216        this(cont, 0);
217    }
218
219    static {
220        Timeouts.initDefault("JTextComponentOperator.PushKeyTimeout", PUSH_KEY_TIMEOUT);
221        Timeouts.initDefault("JTextComponentOperator.BetweenKeysTimeout", BETWEEN_KEYS_TIMEOUT);
222        Timeouts.initDefault("JTextComponentOperator.ChangeCaretPositionTimeout", CHANGE_CARET_POSITION_TIMEOUT);
223        Timeouts.initDefault("JTextComponentOperator.TypeTextTimeout", TYPE_TEXT_TIMEOUT);
224    }
225
226    /**
227     * Searches JTextComponent in container.
228     *
229     * @param cont Container to search component in.
230     * @param chooser a component chooser specifying searching criteria.
231     * @param index Ordinal component index.
232     * @return JTextComponent instance or null if component was not found.
233     */
234    public static JTextComponent findJTextComponent(Container cont, ComponentChooser chooser, int index) {
235        return (JTextComponent) findComponent(cont, new JTextComponentFinder(chooser), index);
236    }
237
238    /**
239     * Searches JTextComponent in container.
240     *
241     * @param cont Container to search component in.
242     * @param chooser a component chooser specifying searching criteria.
243     * @return JTextComponent instance or null if component was not found.
244     */
245    public static JTextComponent findJTextComponent(Container cont, ComponentChooser chooser) {
246        return findJTextComponent(cont, chooser, 0);
247    }
248
249    /**
250     * Searches JTextComponent by text.
251     *
252     * @param cont Container to search component in.
253     * @param text Component text.
254     * @param ce Compare text exactly.
255     * @param ccs Compare text case sensitively.
256     * @param index Ordinal component index.
257     * @return JTextComponent instance or null if component was not found.
258     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
259     */
260    public static JTextComponent findJTextComponent(Container cont, String text, boolean ce, boolean ccs, int index) {
261        return findJTextComponent(cont, new JTextComponentByTextFinder(text, new DefaultStringComparator(ce, ccs)), index);
262    }
263
264    /**
265     * Searches JTextComponent by text.
266     *
267     * @param cont Container to search component in.
268     * @param text Component text.
269     * @param ce Compare text exactly.
270     * @param ccs Compare text case sensitively.
271     * @return JTextComponent instance or null if component was not found.
272     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
273     */
274    public static JTextComponent findJTextComponent(Container cont, String text, boolean ce, boolean ccs) {
275        return findJTextComponent(cont, text, ce, ccs, 0);
276    }
277
278    /**
279     * Waits JTextComponent in container.
280     *
281     * @param cont Container to search component in.
282     * @param chooser a component chooser specifying searching criteria.
283     * @param index Ordinal component index.
284     * @return JTextComponent instance.
285     * @throws TimeoutExpiredException
286     */
287    public static JTextComponent waitJTextComponent(final Container cont, final ComponentChooser chooser, final int index) {
288        return (JTextComponent) waitComponent(cont, new JTextComponentFinder(chooser), index);
289    }
290
291    /**
292     * Waits JTextComponent in container.
293     *
294     * @param cont Container to search component in.
295     * @param chooser a component chooser specifying searching criteria.
296     * @return JTextComponent instance.
297     * @throws TimeoutExpiredException
298     */
299    public static JTextComponent waitJTextComponent(Container cont, ComponentChooser chooser) {
300        return waitJTextComponent(cont, chooser, 0);
301    }
302
303    /**
304     * Waits JTextComponent by text.
305     *
306     * @param cont Container to search component in.
307     * @param text Component text.
308     * @param ce Compare text exactly.
309     * @param ccs Compare text case sensitively.
310     * @param index Ordinal component index.
311     * @return JTextComponent instance.
312     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
313     * @throws TimeoutExpiredException
314     */
315    public static JTextComponent waitJTextComponent(Container cont, String text, boolean ce, boolean ccs, int index) {
316        return waitJTextComponent(cont, new JTextComponentByTextFinder(text, new DefaultStringComparator(ce, ccs)), index);
317    }
318
319    /**
320     * Waits JTextComponent by text.
321     *
322     * @param cont Container to search component in.
323     * @param text Component text.
324     * @param ce Compare text exactly.
325     * @param ccs Compare text case sensitively.
326     * @return JTextComponent instance.
327     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
328     * @throws TimeoutExpiredException
329     */
330    public static JTextComponent waitJTextComponent(Container cont, String text, boolean ce, boolean ccs) {
331        return waitJTextComponent(cont, text, ce, ccs, 0);
332    }
333
334    @Override
335    public void setTimeouts(Timeouts times) {
336        timeouts = times;
337        timeouts.setTimeout("ComponentOperator.PushKeyTimeout",
338                timeouts.getTimeout("JTextComponentOperator.PushKeyTimeout"));
339        super.setTimeouts(timeouts);
340    }
341
342    @Override
343    public Timeouts getTimeouts() {
344        return timeouts;
345    }
346
347    @Override
348    public void setOutput(TestOut out) {
349        output = out;
350        super.setOutput(output.createErrorOutput());
351    }
352
353    @Override
354    public TestOut getOutput() {
355        return output;
356    }
357
358    @Override
359    public void copyEnvironment(Operator anotherOperator) {
360        super.copyEnvironment(anotherOperator);
361        driver
362                = (TextDriver) DriverManager.
363                getDriver(DriverManager.TEXT_DRIVER_ID,
364                        getClass(),
365                        anotherOperator.getProperties());
366    }
367
368    /**
369     * Finds start text position.
370     *
371     * @param text Text to be searched.
372     * @param tChooser Additional search criteria.
373     * @param index Index of text instance (first instance has index 0)
374     * @return Caret position correspondent to text start.
375     * @see JTextComponentOperator.TextChooser
376     */
377    public int getPositionByText(String text, TextChooser tChooser, int index) {
378        output.printLine("Find " + tChooser.getDescription() + "\"" + text
379                + "\" text in text component\n    : "
380                + toStringSource());
381        output.printGolden("Find " + tChooser.getDescription() + "\"" + text
382                + "\" text in text component");
383        String allText = getDisplayedText();
384        Document doc = getDocument();
385        int position = 0;
386        int ind = 0;
387        while ((position = allText.indexOf(text, position)) >= 0) {
388            if (tChooser.checkPosition(doc, position)) {
389                if (ind == index) {
390                    return position;
391                } else {
392                    ind++;
393                }
394            }
395            position = position + text.length();
396        }
397        return -1;
398    }
399
400    /**
401     * Finds start text position.
402     *
403     * @param text Text to be searched.
404     * @param tChooser Additional search criteria.
405     * @return Caret position correspondent to text start.
406     */
407    public int getPositionByText(String text, TextChooser tChooser) {
408        return getPositionByText(text, tChooser, 0);
409    }
410
411    /**
412     * Finds start text position.
413     *
414     * @param text Text to be searched.
415     * @param index Index of text instance (first instance has index 0)
416     * @return Caret position correspondent to text start.
417     */
418    public int getPositionByText(String text, int index) {
419        return (getPositionByText(text, new TextChooser() {
420            @Override
421            public boolean checkPosition(Document doc, int offset) {
422                return true;
423            }
424
425            @Override
426            public String getDescription() {
427                return "any";
428            }
429
430            @Override
431            public String toString() {
432                return "JTextComponentOperator.getPositionByText.TextChooser{description = " + getDescription() + '}';
433            }
434        }, index));
435    }
436
437    /**
438     * Finds start text position.
439     *
440     * @param text Text to be searched.
441     * @return Caret position correspondent to text start.
442     */
443    public int getPositionByText(String text) {
444        return getPositionByText(text, 0);
445    }
446
447    /**
448     * Requests a focus, clears text, types new one and pushes Enter.
449     *
450     * @param text New text value. Shouldn't include final '\n'.
451     * @throws TimeoutExpiredException
452     */
453    public void enterText(final String text) {
454        makeComponentVisible();
455        produceTimeRestricted(new Action<Void, Void>() {
456            @Override
457            public Void launch(Void obj) {
458                driver.enterText(JTextComponentOperator.this, text);
459                return null;
460            }
461
462            @Override
463            public String getDescription() {
464                return "Text entering";
465            }
466
467            @Override
468            public String toString() {
469                return "JTextComponentOperator.enterText.Action{description = " + getDescription() + '}';
470            }
471        }, "JTextComponentOperator.TypeTextTimeout");
472    }
473
474    /**
475     * Changes caret position.
476     *
477     * @param position Position to move caret to.
478     * @see #changeCaretPosition(String, int, boolean)
479     * @throws TimeoutExpiredException
480     */
481    public void changeCaretPosition(final int position) {
482        output.printLine("Change caret position to " + Integer.toString(position));
483        makeComponentVisible();
484        produceTimeRestricted(new Action<Void, Void>() {
485            @Override
486            public Void launch(Void obj) {
487                driver.changeCaretPosition(JTextComponentOperator.this, position);
488                return null;
489            }
490
491            @Override
492            public String getDescription() {
493                return "Caret moving";
494            }
495
496            @Override
497            public String toString() {
498                return "JTextComponentOperator.changeCaretPosition.Action{description = " + getDescription() + '}';
499            }
500        }, "JTextComponentOperator.ChangeCaretPositionTimeout");
501        if (getVerification()) {
502            waitCaretPosition(position);
503        }
504    }
505
506    /**
507     * Puts caret before or after text.
508     *
509     * @param text Text to be searched.
510     * @param index Index of text instance (first instance has index 0)
511     * @param before If true put caret before text, otherwise after.
512     * @see #changeCaretPosition(int)
513     * @see #getPositionByText(String, int)
514     * @throws TimeoutExpiredException
515     * @throws NoSuchTextException
516     */
517    public void changeCaretPosition(String text, int index, boolean before) {
518        output.printLine("Put caret "
519                + (before ? "before" : "after") + " "
520                + Integer.toString(index) + "'th instance of \""
521                + text + "\" text");
522        makeComponentVisible();
523        int offset = getPositionByText(text, index);
524        if (offset == -1) {
525            throw (new NoSuchTextException(text));
526        }
527        offset = before ? offset : offset + text.length();
528        changeCaretPosition(offset);
529    }
530
531    /**
532     * Puts caret before or after text.
533     *
534     * @param text Text to be searched.
535     * @param before If true put caret before text, otherwise after.
536     * @see #changeCaretPosition(int)
537     * @see #getPositionByText(String, int)
538     * @throws TimeoutExpiredException
539     * @throws NoSuchTextException
540     */
541    public void changeCaretPosition(String text, boolean before) {
542        changeCaretPosition(text, 0, before);
543    }
544
545    /**
546     * Types text starting from known position. If verification mode is on,
547     * checks that right text has been typed and caret has been moved to right
548     * position.
549     *
550     * @param text Text to be typed.
551     * @param caretPosition Position to start type text
552     * @see #typeText(String)
553     * @throws TimeoutExpiredException
554     * @throws NoSuchTextException
555     */
556    public void typeText(final String text, final int caretPosition) {
557        output.printLine("Typing text \"" + text + "\" from "
558                + Integer.toString(caretPosition) + " position "
559                + "in text component\n    : "
560                + toStringSource());
561        output.printGolden("Typing text \"" + text + "\" in text component");
562        makeComponentVisible();
563        produceTimeRestricted(new Action<Void, Void>() {
564            @Override
565            public Void launch(Void obj) {
566                driver.typeText(JTextComponentOperator.this, text, caretPosition);
567                return null;
568            }
569
570            @Override
571            public String getDescription() {
572                return "Text typing";
573            }
574
575            @Override
576            public String toString() {
577                return "JTextComponentOperator.typeText.Action{description = " + getDescription() + '}';
578            }
579        }, "JTextComponentOperator.TypeTextTimeout");
580        if (getVerification()) {
581            waitText(text, -1);
582        }
583    }
584
585    /**
586     * Types text starting from the current position.
587     *
588     * @param text Text to be typed.
589     * @see #typeText(String, int)
590     * @throws TimeoutExpiredException
591     */
592    public void typeText(String text) {
593        typeText(text, getCaretPosition());
594    }
595
596    /**
597     * Selects a part of text.
598     *
599     * @param startPosition Start caret position
600     * @param finalPosition Final caret position
601     * @see #selectText(String, int)
602     * @see #selectText(String)
603     * @throws TimeoutExpiredException
604     */
605    public void selectText(final int startPosition, final int finalPosition) {
606        output.printLine("Select text from "
607                + Integer.toString(startPosition) + " to "
608                + Integer.toString(finalPosition)
609                + " in text component\n    : "
610                + toStringSource());
611        makeComponentVisible();
612        produceTimeRestricted(new Action<Void, Void>() {
613            @Override
614            public Void launch(Void obj) {
615                driver.selectText(JTextComponentOperator.this, startPosition, finalPosition);
616                return null;
617            }
618
619            @Override
620            public String getDescription() {
621                return "Text selecting";
622            }
623
624            @Override
625            public String toString() {
626                return "JTextComponentOperator.selectText.Action{description = " + getDescription() + '}';
627            }
628        }, "JTextComponentOperator.TypeTextTimeout");
629    }
630
631    /**
632     * Selects a part of text.
633     *
634     * @param text Text to be selected
635     * @param index Index of text instance (first instance has index 0)
636     * @see #selectText(int, int)
637     * @see #selectText(String)
638     * @see #getPositionByText(String, int)
639     * @throws TimeoutExpiredException
640     * @throws NoSuchTextException
641     */
642    public void selectText(String text, int index) {
643        output.printLine("Select "
644                + Integer.toString(index) + "'th instance of \""
645                + text + "\" text in component\n    : "
646                + toStringSource());
647        makeComponentVisible();
648        int start = getPositionByText(text, index);
649        if (start == -1) {
650            throw (new NoSuchTextException(text));
651        }
652        selectText(start, start + text.length());
653    }
654
655    /**
656     * Selects a part of text.
657     *
658     * @param text Text to be selected
659     * @see #selectText(String, int)
660     * @see #selectText(int, int)
661     * @throws TimeoutExpiredException
662     * @throws NoSuchTextException
663     */
664    public void selectText(String text) {
665        selectText(text, 0);
666    }
667
668    /**
669     * Clears text.
670     *
671     * @throws TimeoutExpiredException
672     */
673    public void clearText() {
674        output.printLine("Clearing text in text component\n    : "
675                + toStringSource());
676        output.printGolden("Clearing text in text component");
677        makeComponentVisible();
678        produceTimeRestricted(new Action<Void, Void>() {
679            @Override
680            public Void launch(Void obj) {
681                driver.clearText(JTextComponentOperator.this);
682                return null;
683            }
684
685            @Override
686            public String getDescription() {
687                return "Text clearing";
688            }
689
690            @Override
691            public String toString() {
692                return "JTextComponentOperator.clearText.Action{description = " + getDescription() + '}';
693            }
694        }, "JTextComponentOperator.TypeTextTimeout");
695    }
696
697    /**
698     * Scrolls to a text poistion.
699     *
700     * @param position a position to scroll.
701     * @throws TimeoutExpiredException
702     */
703    public void scrollToPosition(int position) {
704        output.printTrace("Scroll JTextComponent to " + Integer.toString(position) + " position\n    : "
705                + toStringSource());
706        output.printGolden("Scroll JTextComponent to " + Integer.toString(position) + " position");
707        makeComponentVisible();
708        //try to find JScrollPane under.
709        JScrollPane scroll = (JScrollPane) getContainer(new JScrollPaneOperator.JScrollPaneFinder(ComponentSearcher.
710                getTrueChooser("JScrollPane")));
711        if (scroll == null) {
712            return;
713        }
714        JScrollPaneOperator scroller = new JScrollPaneOperator(scroll);
715        scroller.copyEnvironment(this);
716        scroller.setVisualizer(new EmptyVisualizer());
717        Rectangle rect = modelToView(position);
718        scroller.scrollToComponentRectangle(getSource(),
719                (int) rect.getX(),
720                (int) rect.getY(),
721                (int) rect.getWidth(),
722                (int) rect.getHeight());
723    }
724
725    /**
726     * Returns text which is really displayed. Results returned by
727     * {@code getText()} and {@code getDisplayedText()} are different
728     * if text component is used to display
729     * {@code javax.swing.text.StyledDocument}
730     *
731     * @return the text which is displayed.
732     */
733    public String getDisplayedText() {
734        try {
735            Document doc = getDocument();
736            return doc.getText(0, doc.getLength());
737        } catch (BadLocationException e) {
738            throw (new JemmyException("Exception during text operation with\n    : "
739                    + toStringSource(), e));
740        }
741    }
742
743    /**
744     * Wait for text to be displayed starting from certain position.
745     *
746     * @param text text to wait.
747     * @param position starting text position.
748     */
749    public void waitText(final String text, final int position) {
750        getOutput().printLine("Wait \"" + text + "\" text starting from "
751                + Integer.toString(position) + " position in component \n    : "
752                + toStringSource());
753        getOutput().printGolden("Wait \"" + text + "\" text starting from "
754                + Integer.toString(position) + " position");
755        waitState(new ComponentChooser() {
756            @Override
757            public boolean checkComponent(Component comp) {
758                String alltext = getDisplayedText();
759                if (position >= 0) {
760                    if (position + text.length() <= alltext.length()) {
761                        return (alltext.substring(position, position + text.length()).
762                                equals(text));
763                    } else {
764                        return false;
765                    }
766                } else {
767                    return alltext.indexOf(text) >= 0;
768                }
769            }
770
771            @Override
772            public String getDescription() {
773                return ("Has \"" + text + "\" text starting from "
774                        + Integer.toString(position) + " position");
775            }
776
777            @Override
778            public String toString() {
779                return "JTextComponentOperator.waitText.ComponentChooser{description = " + getDescription() + '}';
780            }
781        });
782    }
783
784    /**
785     * Waits for certain text.
786     *
787     * @param text Text to be compared by getComparator() comparator.
788     */
789    public void waitText(String text) {
790        getOutput().printLine("Wait \"" + text + "\" text in component \n    : "
791                + toStringSource());
792        getOutput().printGolden("Wait \"" + text + "\" text");
793        waitState(new JTextComponentByTextFinder(text, getComparator()));
794    }
795
796    /**
797     * Wait for caret to be moved to certain position.
798     *
799     * @param position a position which caret supposed to be moved to.
800     */
801    public void waitCaretPosition(final int position) {
802        getOutput().printLine("Wait caret to be at \"" + Integer.toString(position)
803                + " position in component \n    : "
804                + toStringSource());
805        getOutput().printGolden("Wait caret to be at \"" + Integer.toString(position)
806                + " position");
807        waitState(new ComponentChooser() {
808            @Override
809            public boolean checkComponent(Component comp) {
810                return getCaretPosition() == position;
811            }
812
813            @Override
814            public String getDescription() {
815                return "Has caret at " + Integer.toString(position) + " position";
816            }
817
818            @Override
819            public String toString() {
820                return "JTextComponentOperator.waitCaretPosition.ComponentChooser{description = " + getDescription() + '}';
821            }
822        });
823    }
824
825    @Override
826    public Hashtable<String, Object> getDump() {
827        Hashtable<String, Object> result = super.getDump();
828        result.put(TEXT_DPROP, ((JTextComponent) getSource()).getText());
829        if (((JTextComponent) getSource()).getSelectedText() != null
830                && !((JTextComponent) getSource()).getSelectedText().equals("")) {
831            result.put(SELECTED_TEXT_DPROP, ((JTextComponent) getSource()).getSelectedText());
832        }
833        result.put(IS_EDITABLE_DPROP, ((JTextComponent) getSource()).isEditable() ? "true" : "false");
834        return result;
835    }
836
837    ////////////////////////////////////////////////////////
838    //Mapping                                             //
839    /**
840     * Maps {@code JTextComponent.addCaretListener(CaretListener)} through queue
841     */
842    public void addCaretListener(final CaretListener caretListener) {
843        runMapping(new MapVoidAction("addCaretListener") {
844            @Override
845            public void map() {
846                ((JTextComponent) getSource()).addCaretListener(caretListener);
847            }
848        });
849    }
850
851    /**
852     * Maps {@code JTextComponent.copy()} through queue
853     */
854    public void copy() {
855        runMapping(new MapVoidAction("copy") {
856            @Override
857            public void map() {
858                ((JTextComponent) getSource()).copy();
859            }
860        });
861    }
862
863    /**
864     * Maps {@code JTextComponent.cut()} through queue
865     */
866    public void cut() {
867        runMapping(new MapVoidAction("cut") {
868            @Override
869            public void map() {
870                ((JTextComponent) getSource()).cut();
871            }
872        });
873    }
874
875    /**
876     * Maps {@code JTextComponent.getActions()} through queue
877     */
878    public javax.swing.Action[] getActions() {
879        return ((javax.swing.Action[]) runMapping(new MapAction<Object>("getActions") {
880            @Override
881            public Object map() {
882                return ((JTextComponent) getSource()).getActions();
883            }
884        }));
885    }
886
887    /**
888     * Maps {@code JTextComponent.getCaret()} through queue
889     */
890    public Caret getCaret() {
891        return (runMapping(new MapAction<Caret>("getCaret") {
892            @Override
893            public Caret map() {
894                return ((JTextComponent) getSource()).getCaret();
895            }
896        }));
897    }
898
899    /**
900     * Maps {@code JTextComponent.getCaretColor()} through queue
901     */
902    public Color getCaretColor() {
903        return (runMapping(new MapAction<Color>("getCaretColor") {
904            @Override
905            public Color map() {
906                return ((JTextComponent) getSource()).getCaretColor();
907            }
908        }));
909    }
910
911    /**
912     * Maps {@code JTextComponent.getCaretPosition()} through queue
913     */
914    public int getCaretPosition() {
915        return (runMapping(new MapIntegerAction("getCaretPosition") {
916            @Override
917            public int map() {
918                return ((JTextComponent) getSource()).getCaretPosition();
919            }
920        }));
921    }
922
923    /**
924     * Maps {@code JTextComponent.getDisabledTextColor()} through queue
925     */
926    public Color getDisabledTextColor() {
927        return (runMapping(new MapAction<Color>("getDisabledTextColor") {
928            @Override
929            public Color map() {
930                return ((JTextComponent) getSource()).getDisabledTextColor();
931            }
932        }));
933    }
934
935    /**
936     * Maps {@code JTextComponent.getDocument()} through queue
937     */
938    public Document getDocument() {
939        return (runMapping(new MapAction<Document>("getDocument") {
940            @Override
941            public Document map() {
942                return ((JTextComponent) getSource()).getDocument();
943            }
944        }));
945    }
946
947    /**
948     * Maps {@code JTextComponent.getFocusAccelerator()} through queue
949     */
950    public char getFocusAccelerator() {
951        return (runMapping(new MapCharacterAction("getFocusAccelerator") {
952            @Override
953            public char map() {
954                return ((JTextComponent) getSource()).getFocusAccelerator();
955            }
956        }));
957    }
958
959    /**
960     * Maps {@code JTextComponent.getHighlighter()} through queue
961     */
962    public Highlighter getHighlighter() {
963        return (runMapping(new MapAction<Highlighter>("getHighlighter") {
964            @Override
965            public Highlighter map() {
966                return ((JTextComponent) getSource()).getHighlighter();
967            }
968        }));
969    }
970
971    /**
972     * Maps {@code JTextComponent.getKeymap()} through queue
973     */
974    public Keymap getKeymap() {
975        return (runMapping(new MapAction<Keymap>("getKeymap") {
976            @Override
977            public Keymap map() {
978                return ((JTextComponent) getSource()).getKeymap();
979            }
980        }));
981    }
982
983    /**
984     * Maps {@code JTextComponent.getMargin()} through queue
985     */
986    public Insets getMargin() {
987        return (runMapping(new MapAction<Insets>("getMargin") {
988            @Override
989            public Insets map() {
990                return ((JTextComponent) getSource()).getMargin();
991            }
992        }));
993    }
994
995    /**
996     * Maps {@code JTextComponent.getPreferredScrollableViewportSize()}
997     * through queue
998     */
999    public Dimension getPreferredScrollableViewportSize() {
1000        return (runMapping(new MapAction<Dimension>("getPreferredScrollableViewportSize") {
1001            @Override
1002            public Dimension map() {
1003                return ((JTextComponent) getSource()).getPreferredScrollableViewportSize();
1004            }
1005        }));
1006    }
1007
1008    /**
1009     * Maps
1010     * {@code JTextComponent.getScrollableBlockIncrement(Rectangle, int, int)}
1011     * through queue
1012     */
1013    public int getScrollableBlockIncrement(final Rectangle rectangle, final int i, final int i1) {
1014        return (runMapping(new MapIntegerAction("getScrollableBlockIncrement") {
1015            @Override
1016            public int map() {
1017                return ((JTextComponent) getSource()).getScrollableBlockIncrement(rectangle, i, i1);
1018            }
1019        }));
1020    }
1021
1022    /**
1023     * Maps {@code JTextComponent.getScrollableTracksViewportHeight()}
1024     * through queue
1025     */
1026    public boolean getScrollableTracksViewportHeight() {
1027        return (runMapping(new MapBooleanAction("getScrollableTracksViewportHeight") {
1028            @Override
1029            public boolean map() {
1030                return ((JTextComponent) getSource()).getScrollableTracksViewportHeight();
1031            }
1032        }));
1033    }
1034
1035    /**
1036     * Maps {@code JTextComponent.getScrollableTracksViewportWidth()}
1037     * through queue
1038     */
1039    public boolean getScrollableTracksViewportWidth() {
1040        return (runMapping(new MapBooleanAction("getScrollableTracksViewportWidth") {
1041            @Override
1042            public boolean map() {
1043                return ((JTextComponent) getSource()).getScrollableTracksViewportWidth();
1044            }
1045        }));
1046    }
1047
1048    /**
1049     * Maps
1050     * {@code JTextComponent.getScrollableUnitIncrement(Rectangle, int, int)}
1051     * through queue
1052     */
1053    public int getScrollableUnitIncrement(final Rectangle rectangle, final int i, final int i1) {
1054        return (runMapping(new MapIntegerAction("getScrollableUnitIncrement") {
1055            @Override
1056            public int map() {
1057                return ((JTextComponent) getSource()).getScrollableUnitIncrement(rectangle, i, i1);
1058            }
1059        }));
1060    }
1061
1062    /**
1063     * Maps {@code JTextComponent.getSelectedText()} through queue
1064     */
1065    public String getSelectedText() {
1066        return (runMapping(new MapAction<String>("getSelectedText") {
1067            @Override
1068            public String map() {
1069                return ((JTextComponent) getSource()).getSelectedText();
1070            }
1071        }));
1072    }
1073
1074    /**
1075     * Maps {@code JTextComponent.getSelectedTextColor()} through queue
1076     */
1077    public Color getSelectedTextColor() {
1078        return (runMapping(new MapAction<Color>("getSelectedTextColor") {
1079            @Override
1080            public Color map() {
1081                return ((JTextComponent) getSource()).getSelectedTextColor();
1082            }
1083        }));
1084    }
1085
1086    /**
1087     * Maps {@code JTextComponent.getSelectionColor()} through queue
1088     */
1089    public Color getSelectionColor() {
1090        return (runMapping(new MapAction<Color>("getSelectionColor") {
1091            @Override
1092            public Color map() {
1093                return ((JTextComponent) getSource()).getSelectionColor();
1094            }
1095        }));
1096    }
1097
1098    /**
1099     * Maps {@code JTextComponent.getSelectionEnd()} through queue
1100     */
1101    public int getSelectionEnd() {
1102        return (runMapping(new MapIntegerAction("getSelectionEnd") {
1103            @Override
1104            public int map() {
1105                return ((JTextComponent) getSource()).getSelectionEnd();
1106            }
1107        }));
1108    }
1109
1110    /**
1111     * Maps {@code JTextComponent.getSelectionStart()} through queue
1112     */
1113    public int getSelectionStart() {
1114        return (runMapping(new MapIntegerAction("getSelectionStart") {
1115            @Override
1116            public int map() {
1117                return ((JTextComponent) getSource()).getSelectionStart();
1118            }
1119        }));
1120    }
1121
1122    /**
1123     * Maps {@code JTextComponent.getText()} through queue
1124     */
1125    public String getText() {
1126        return (runMapping(new MapAction<String>("getText") {
1127            @Override
1128            public String map() {
1129                return ((JTextComponent) getSource()).getText();
1130            }
1131        }));
1132    }
1133
1134    /**
1135     * Maps {@code JTextComponent.getText(int, int)} through queue
1136     */
1137    public String getText(final int i, final int i1) {
1138        return (runMapping(new MapAction<String>("getText") {
1139            @Override
1140            public String map() throws BadLocationException {
1141                return ((JTextComponent) getSource()).getText(i, i1);
1142            }
1143        }));
1144    }
1145
1146    /**
1147     * Maps {@code JTextComponent.getUI()} through queue
1148     */
1149    public TextUI getUI() {
1150        return (runMapping(new MapAction<TextUI>("getUI") {
1151            @Override
1152            public TextUI map() {
1153                return ((JTextComponent) getSource()).getUI();
1154            }
1155        }));
1156    }
1157
1158    /**
1159     * Maps {@code JTextComponent.isEditable()} through queue
1160     */
1161    public boolean isEditable() {
1162        return (runMapping(new MapBooleanAction("isEditable") {
1163            @Override
1164            public boolean map() {
1165                return ((JTextComponent) getSource()).isEditable();
1166            }
1167        }));
1168    }
1169
1170    /**
1171     * Maps {@code JTextComponent.modelToView(int)} through queue
1172     */
1173    public Rectangle modelToView(final int i) {
1174        return (runMapping(new MapAction<Rectangle>("modelToView") {
1175            @Override
1176            public Rectangle map() throws BadLocationException {
1177                return ((JTextComponent) getSource()).modelToView(i);
1178            }
1179        }));
1180    }
1181
1182    /**
1183     * Maps {@code JTextComponent.moveCaretPosition(int)} through queue
1184     */
1185    public void moveCaretPosition(final int i) {
1186        runMapping(new MapVoidAction("moveCaretPosition") {
1187            @Override
1188            public void map() {
1189                ((JTextComponent) getSource()).moveCaretPosition(i);
1190            }
1191        });
1192    }
1193
1194    /**
1195     * Maps {@code JTextComponent.paste()} through queue
1196     */
1197    public void paste() {
1198        runMapping(new MapVoidAction("paste") {
1199            @Override
1200            public void map() {
1201                ((JTextComponent) getSource()).paste();
1202            }
1203        });
1204    }
1205
1206    /**
1207     * Maps {@code JTextComponent.read(Reader, Object)} through queue
1208     */
1209    public void read(final Reader reader, final Object object) {
1210        runMapping(new MapVoidAction("read") {
1211            @Override
1212            public void map() throws IOException {
1213                ((JTextComponent) getSource()).read(reader, object);
1214            }
1215        });
1216    }
1217
1218    /**
1219     * Maps {@code JTextComponent.removeCaretListener(CaretListener)}
1220     * through queue
1221     */
1222    public void removeCaretListener(final CaretListener caretListener) {
1223        runMapping(new MapVoidAction("removeCaretListener") {
1224            @Override
1225            public void map() {
1226                ((JTextComponent) getSource()).removeCaretListener(caretListener);
1227            }
1228        });
1229    }
1230
1231    /**
1232     * Maps {@code JTextComponent.replaceSelection(String)} through queue
1233     */
1234    public void replaceSelection(final String string) {
1235        runMapping(new MapVoidAction("replaceSelection") {
1236            @Override
1237            public void map() {
1238                ((JTextComponent) getSource()).replaceSelection(string);
1239            }
1240        });
1241    }
1242
1243    /**
1244     * Maps {@code JTextComponent.select(int, int)} through queue
1245     */
1246    public void select(final int i, final int i1) {
1247        runMapping(new MapVoidAction("select") {
1248            @Override
1249            public void map() {
1250                ((JTextComponent) getSource()).select(i, i1);
1251            }
1252        });
1253    }
1254
1255    /**
1256     * Maps {@code JTextComponent.selectAll()} through queue
1257     */
1258    public void selectAll() {
1259        runMapping(new MapVoidAction("selectAll") {
1260            @Override
1261            public void map() {
1262                ((JTextComponent) getSource()).selectAll();
1263            }
1264        });
1265    }
1266
1267    /**
1268     * Maps {@code JTextComponent.setCaret(Caret)} through queue
1269     */
1270    public void setCaret(final Caret caret) {
1271        runMapping(new MapVoidAction("setCaret") {
1272            @Override
1273            public void map() {
1274                ((JTextComponent) getSource()).setCaret(caret);
1275            }
1276        });
1277    }
1278
1279    /**
1280     * Maps {@code JTextComponent.setCaretColor(Color)} through queue
1281     */
1282    public void setCaretColor(final Color color) {
1283        runMapping(new MapVoidAction("setCaretColor") {
1284            @Override
1285            public void map() {
1286                ((JTextComponent) getSource()).setCaretColor(color);
1287            }
1288        });
1289    }
1290
1291    /**
1292     * Maps {@code JTextComponent.setCaretPosition(int)} through queue
1293     */
1294    public void setCaretPosition(final int i) {
1295        runMapping(new MapVoidAction("setCaretPosition") {
1296            @Override
1297            public void map() {
1298                ((JTextComponent) getSource()).setCaretPosition(i);
1299            }
1300        });
1301    }
1302
1303    /**
1304     * Maps {@code JTextComponent.setDisabledTextColor(Color)} through queue
1305     */
1306    public void setDisabledTextColor(final Color color) {
1307        runMapping(new MapVoidAction("setDisabledTextColor") {
1308            @Override
1309            public void map() {
1310                ((JTextComponent) getSource()).setDisabledTextColor(color);
1311            }
1312        });
1313    }
1314
1315    /**
1316     * Maps {@code JTextComponent.setDocument(Document)} through queue
1317     */
1318    public void setDocument(final Document document) {
1319        runMapping(new MapVoidAction("setDocument") {
1320            @Override
1321            public void map() {
1322                ((JTextComponent) getSource()).setDocument(document);
1323            }
1324        });
1325    }
1326
1327    /**
1328     * Maps {@code JTextComponent.setEditable(boolean)} through queue
1329     */
1330    public void setEditable(final boolean b) {
1331        runMapping(new MapVoidAction("setEditable") {
1332            @Override
1333            public void map() {
1334                ((JTextComponent) getSource()).setEditable(b);
1335            }
1336        });
1337    }
1338
1339    /**
1340     * Maps {@code JTextComponent.setFocusAccelerator(char)} through queue
1341     */
1342    public void setFocusAccelerator(final char c) {
1343        runMapping(new MapVoidAction("setFocusAccelerator") {
1344            @Override
1345            public void map() {
1346                ((JTextComponent) getSource()).setFocusAccelerator(c);
1347            }
1348        });
1349    }
1350
1351    /**
1352     * Maps {@code JTextComponent.setHighlighter(Highlighter)} through queue
1353     */
1354    public void setHighlighter(final Highlighter highlighter) {
1355        runMapping(new MapVoidAction("setHighlighter") {
1356            @Override
1357            public void map() {
1358                ((JTextComponent) getSource()).setHighlighter(highlighter);
1359            }
1360        });
1361    }
1362
1363    /**
1364     * Maps {@code JTextComponent.setKeymap(Keymap)} through queue
1365     */
1366    public void setKeymap(final Keymap keymap) {
1367        runMapping(new MapVoidAction("setKeymap") {
1368            @Override
1369            public void map() {
1370                ((JTextComponent) getSource()).setKeymap(keymap);
1371            }
1372        });
1373    }
1374
1375    /**
1376     * Maps {@code JTextComponent.setMargin(Insets)} through queue
1377     */
1378    public void setMargin(final Insets insets) {
1379        runMapping(new MapVoidAction("setMargin") {
1380            @Override
1381            public void map() {
1382                ((JTextComponent) getSource()).setMargin(insets);
1383            }
1384        });
1385    }
1386
1387    /**
1388     * Maps {@code JTextComponent.setSelectedTextColor(Color)} through queue
1389     */
1390    public void setSelectedTextColor(final Color color) {
1391        runMapping(new MapVoidAction("setSelectedTextColor") {
1392            @Override
1393            public void map() {
1394                ((JTextComponent) getSource()).setSelectedTextColor(color);
1395            }
1396        });
1397    }
1398
1399    /**
1400     * Maps {@code JTextComponent.setSelectionColor(Color)} through queue
1401     */
1402    public void setSelectionColor(final Color color) {
1403        runMapping(new MapVoidAction("setSelectionColor") {
1404            @Override
1405            public void map() {
1406                ((JTextComponent) getSource()).setSelectionColor(color);
1407            }
1408        });
1409    }
1410
1411    /**
1412     * Maps {@code JTextComponent.setSelectionEnd(int)} through queue
1413     */
1414    public void setSelectionEnd(final int i) {
1415        runMapping(new MapVoidAction("setSelectionEnd") {
1416            @Override
1417            public void map() {
1418                ((JTextComponent) getSource()).setSelectionEnd(i);
1419            }
1420        });
1421    }
1422
1423    /**
1424     * Maps {@code JTextComponent.setSelectionStart(int)} through queue
1425     */
1426    public void setSelectionStart(final int i) {
1427        runMapping(new MapVoidAction("setSelectionStart") {
1428            @Override
1429            public void map() {
1430                ((JTextComponent) getSource()).setSelectionStart(i);
1431            }
1432        });
1433    }
1434
1435    /**
1436     * Maps {@code JTextComponent.setText(String)} through queue
1437     */
1438    public void setText(final String string) {
1439        runMapping(new MapVoidAction("setText") {
1440            @Override
1441            public void map() {
1442                ((JTextComponent) getSource()).setText(string);
1443            }
1444        });
1445    }
1446
1447    /**
1448     * Maps {@code JTextComponent.setUI(TextUI)} through queue
1449     */
1450    public void setUI(final TextUI textUI) {
1451        runMapping(new MapVoidAction("setUI") {
1452            @Override
1453            public void map() {
1454                ((JTextComponent) getSource()).setUI(textUI);
1455            }
1456        });
1457    }
1458
1459    /**
1460     * Maps {@code JTextComponent.viewToModel(Point)} through queue
1461     */
1462    public int viewToModel(final Point point) {
1463        return (runMapping(new MapIntegerAction("viewToModel") {
1464            @Override
1465            public int map() {
1466                return ((JTextComponent) getSource()).viewToModel(point);
1467            }
1468        }));
1469    }
1470
1471    /**
1472     * Maps {@code JTextComponent.write(Writer)} through queue
1473     */
1474    public void write(final Writer writer) {
1475        runMapping(new MapVoidAction("write") {
1476            @Override
1477            public void map() throws IOException {
1478                ((JTextComponent) getSource()).write(writer);
1479            }
1480        });
1481    }
1482
1483    //End of mapping                                      //
1484    ////////////////////////////////////////////////////////
1485    /**
1486     * Can be throught during a text operation if text has not been found in the
1487     * component.
1488     */
1489    public class NoSuchTextException extends JemmyInputException {
1490
1491        private static final long serialVersionUID = 42L;
1492
1493        /**
1494         * Constructor.
1495         *
1496         * @param text a nonexistent text.
1497         */
1498        public NoSuchTextException(String text) {
1499            super("No such text as \"" + text + "\"", getSource());
1500        }
1501    }
1502
1503    /**
1504     * Interface defining additional text cearch criteria.
1505     *
1506     * @see #getPositionByText(java.lang.String,
1507     * JTextComponentOperator.TextChooser)
1508     */
1509    public interface TextChooser {
1510
1511        /**
1512         * Checkes if position fits the criteria.
1513         *
1514         * @param document a document to be checked.
1515         * @param offset a checked position
1516         * @return true if the position fits the criteria.
1517         */
1518        public boolean checkPosition(Document document, int offset);
1519
1520        /**
1521         * Returns a printable description of the criteria.
1522         *
1523         * @return a description of this chooser.
1524         */
1525        public String getDescription();
1526    }
1527
1528    /**
1529     * Allows to find component by text.
1530     */
1531    public static class JTextComponentByTextFinder implements ComponentChooser {
1532
1533        String label;
1534        StringComparator comparator;
1535
1536        /**
1537         * Constructs JTextComponentByTextFinder.
1538         *
1539         * @param lb a text pattern
1540         * @param comparator specifies string comparision algorithm.
1541         */
1542        public JTextComponentByTextFinder(String lb, StringComparator comparator) {
1543            label = lb;
1544            this.comparator = comparator;
1545        }
1546
1547        /**
1548         * Constructs JTextComponentByTextFinder.
1549         *
1550         * @param lb a text pattern
1551         */
1552        public JTextComponentByTextFinder(String lb) {
1553            this(lb, Operator.getDefaultStringComparator());
1554        }
1555
1556        @Override
1557        public boolean checkComponent(Component comp) {
1558            if (comp instanceof JTextComponent) {
1559                if (((JTextComponent) comp).getText() != null) {
1560                    return (comparator.equals(((JTextComponent) comp).getText(),
1561                            label));
1562                }
1563            }
1564            return false;
1565        }
1566
1567        @Override
1568        public String getDescription() {
1569            return "JTextComponent with text \"" + label + "\"";
1570        }
1571
1572        @Override
1573        public String toString() {
1574            return "JTextComponentByTextFinder{" + "label=" + label + ", comparator=" + comparator + '}';
1575        }
1576    }
1577
1578    /**
1579     * Checks component type.
1580     */
1581    public static class JTextComponentFinder extends Finder {
1582
1583        /**
1584         * Constructs JTextComponentFinder.
1585         *
1586         * @param sf other searching criteria.
1587         */
1588        public JTextComponentFinder(ComponentChooser sf) {
1589            super(JTextComponent.class, sf);
1590        }
1591
1592        /**
1593         * Constructs JTextComponentFinder.
1594         */
1595        public JTextComponentFinder() {
1596            super(JTextComponent.class);
1597        }
1598    }
1599}
1600