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