1 /*
   2  * Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  */
  23 
  24 /*
  25   test
  26   @bug 6497109
  27   @summary TextArea must have selection expanding, and also be autoscrolled, if mouse is dragged from inside.
  28   @author Konstantin Voloshin: area=TextArea
  29   @run applet SelectionAutoscrollTest.html
  30 */
  31 
  32 /**
  33  * SelectionAutoscrollTest.java
  34  *
  35  * summary: TextArea should be auto-scrolled and text should be selected to
  36  *   the end, if mouse is dragged from inside box-for-text to outside it, and
  37  *   is hold pressed there.
  38  */
  39 
  40 
  41 import java.applet.Applet;
  42 import java.awt.Frame;
  43 import java.awt.Panel;
  44 import java.awt.GridLayout;
  45 import java.awt.TextArea;
  46 
  47 import java.awt.Point;
  48 import java.awt.Dimension;
  49 import java.awt.event.MouseEvent;
  50 import java.awt.Robot;
  51 import java.awt.Toolkit;
  52 import test.java.awt.regtesthelpers.Util;
  53 
  54 
  55 public class SelectionAutoscrollTest extends Applet {
  56     TextArea textArea;
  57     Robot robot;
  58     final int desiredSelectionEnd = ('z'-'a'+1)*2;  // 52
  59 
  60     public void start () {
  61         createObjects();
  62         manipulateMouse();
  63         checkResults();
  64     }
  65 
  66     void createObjects() {
  67         textArea = new TextArea( bigString() );
  68         robot = Util.createRobot();
  69 
  70         Panel panel = new Panel();
  71         panel.setLayout( new GridLayout(3,3) );
  72 
  73         for( int y=0; y<3; ++y ) {
  74             for( int x=0; x<3; ++x ) {
  75                 if( x==1 && y==1 ) {
  76                     panel.add( textArea );
  77                 } else {
  78                     panel.add( new Panel() );
  79                 }
  80             }
  81         }
  82 
  83         Frame frame = new Frame( "TextArea cursor icon test" );
  84         frame.setSize( 300, 300 );
  85         frame.add( panel );
  86         frame.setVisible( true );
  87     }
  88 
  89     static String bigString() {
  90         String s = "";
  91         for( char c='a'; c<='z'; ++c ) {
  92             s += c+"\n";
  93         }
  94         return s;
  95     }
  96 
  97     void manipulateMouse() {
  98         moveMouseToCenterOfTextArea();
  99         Util.waitForIdle( robot );
 100 
 101         robot.mousePress( MouseEvent.BUTTON1_MASK );
 102         Util.waitForIdle( robot );
 103 
 104         for( int tremble=0; tremble < desiredSelectionEnd; ++tremble ) {
 105             // Mouse is moved repeatedly here (with conservatively chosen
 106             // ammount of times), to give some time/chance for TextArea to
 107             // autoscroll and for text-selection to expand to the end.
 108             // This is because:
 109             // - On Windows,
 110             //   autoscrolling and selection-expansion happens only once per
 111             //   each mouse-dragged event received, and only for some ammount,
 112             //   not to the end. So, we have to drag mouse repeatedly.
 113             // - on X,
 114             //   only 1 mouse-dragged event is required for autoscrolling/
 115             //   selection-expanding to commence. Once commenced, it will
 116             //   continue to the end of text (provided that mouse-button is
 117             //   hold pressed), but it may take hardly predictable ammount of
 118             //   time. However, repeatedly dragging mouse seems perfectly help
 119             //   here, instead of having to use 'Thread.sleep( ??? )'.
 120             // Note: It's required here to move mouse 2 times to receive the
 121             //   1-st drag-event. After 1-st movement, only mouse-exited event
 122             //   will be generated. If mouse was released after first movement
 123             //   here, we would even get mouse-clicked event (at least for now,
 124             //   and this is probably a bug). But, starting with 2nd iteration,
 125             //   all events received will be mouse-dragged events.
 126 
 127             moveMouseBelowTextArea( tremble%2!=0 );
 128             Util.waitForIdle( robot );
 129         }
 130 
 131         robot.mouseRelease( MouseEvent.BUTTON1_MASK );
 132         Util.waitForIdle( robot );
 133     }
 134 
 135     void moveMouseToCenterOfTextArea() {
 136         Dimension d = textArea.getSize();
 137         Point l = textArea.getLocationOnScreen();
 138         robot.mouseMove( (int)(l.x+d.width*.5), (int)(l.y+d.height*.5) );
 139     }
 140 
 141     void moveMouseBelowTextArea( boolean shift ) {
 142         Dimension d = textArea.getSize();
 143         Point l = textArea.getLocationOnScreen();
 144         int y = (int)(l.y+d.height*1.5);
 145         if( shift ) y+=15;
 146         robot.mouseMove( (int)(l.x+d.width*.5), y );
 147     }
 148 
 149     void checkResults() {
 150         //try { Thread.sleep( 30*1000 ); }
 151         //catch( Exception e ) { throw new RuntimeException( e ); }
 152 
 153         final int currentSelectionEnd = textArea.getSelectionEnd();
 154 
 155         System.out.println(
 156             "TEST: Selection range after test is: ( "
 157             + textArea.getSelectionStart() + ", "
 158             + currentSelectionEnd + " )"
 159         );
 160 
 161         boolean resultOk = ( currentSelectionEnd == desiredSelectionEnd );
 162         String desiredSelectionEndString = "" + desiredSelectionEnd;
 163 
 164         // On Windows, last empty line is surprisingly not selected.
 165         // Even if it's a bug, it's not for this test.
 166         // So, we have 2 acceptable results in this case.
 167         String toolkitName = Toolkit.getDefaultToolkit().getClass().getName();
 168         if( toolkitName.equals("sun.awt.windows.WToolkit") ) {
 169             final int desiredSelectionEnd2 = desiredSelectionEnd-1;  // 51
 170             resultOk |= ( currentSelectionEnd == desiredSelectionEnd2 );
 171             desiredSelectionEndString += " or " + desiredSelectionEnd2;
 172         }
 173 
 174         if( resultOk ) {
 175             System.out.println(
 176                 "TEST: passed: Text is selected to the end"
 177                 + " (expected selection range end is "
 178                 + desiredSelectionEndString + ")."
 179             );
 180         } else {
 181             System.out.println(
 182                 "TEST: FAILED: Text should be selected to the end"
 183                 + " (selection range end should be "
 184                 + desiredSelectionEndString + ")."
 185             );
 186             throw new RuntimeException(
 187                 "TEST: FAILED: Text should be selected to the end, but it is not."
 188             );
 189         }
 190     }
 191 }