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