1 /*
   2   test
   3   @bug       6240202
   4   @summary   Tests that non-focusable List in a Window generates ActionEvent.
   5   @author    anton.tarasov@sun.com: area=awt-list
   6   @run       applet NofocusListDblClickTest.html
   7 */
   8 
   9 import java.awt.*;
  10 import java.awt.event.*;
  11 import java.applet.Applet;
  12 import java.util.concurrent.atomic.AtomicInteger;
  13 import java.lang.reflect.InvocationTargetException;
  14 
  15 public class NofocusListDblClickTest extends Applet {
  16     static final int EXPECTED_ACTION_COUNT = 2;
  17     Robot robot;
  18 
  19     Frame f = new Frame("Owner");
  20     Window w = new Window(f);
  21     List l = new List(3, true);
  22     AtomicInteger actionPerformed = new AtomicInteger(0);
  23 
  24     public static void main(String[] args) {
  25         NofocusListDblClickTest app = new NofocusListDblClickTest();
  26         app.init();
  27         app.start();
  28     }
  29 
  30     public void init() {
  31         try {
  32             robot = new Robot();
  33         } catch (AWTException e) {
  34             throw new RuntimeException("Error: unable to create robot.");
  35         }
  36         this.setLayout (new BorderLayout ());
  37         Sysout.createDialogWithInstructions(new String[]
  38             {"This is an automatic test. Simply wait until it's done."
  39             });
  40     }
  41 
  42     public void start() {
  43         f.setBounds(800, 0, 100, 100);
  44         w.setLocation(800, 150);
  45 
  46         l.add("item 0");
  47         l.add("item 1");
  48         l.add("item 2");
  49 
  50         l.setFocusable(false);
  51 
  52         l.addActionListener(new ActionListener() {
  53                 public void actionPerformed(ActionEvent e) {
  54                     Sysout.println(e.toString());
  55                     synchronized (actionPerformed) {
  56                         if (EXPECTED_ACTION_COUNT == actionPerformed.incrementAndGet()) {
  57                             actionPerformed.notifyAll();
  58                         }
  59                     }
  60                 }
  61             });
  62 
  63         w.add(l);
  64         w.pack();
  65 
  66         f.setVisible(true);
  67         w.setVisible(true);
  68 
  69         waitTillShown(l);
  70 
  71         // ACTION_PERFORMED event happens only on even clicks
  72         clickOn(l);
  73         clickOn(l);
  74         clickOn(l);
  75         clickOn(l);
  76 
  77         synchronized (actionPerformed) {
  78             if (actionPerformed.get() != EXPECTED_ACTION_COUNT) {
  79                 try {
  80                     actionPerformed.wait(3000);
  81                 } catch (InterruptedException e) {
  82                     Sysout.println("Interrupted unexpectedly!");
  83                     throw new RuntimeException(e);
  84                 }
  85             }
  86         }
  87 
  88         if (actionPerformed.get() != EXPECTED_ACTION_COUNT) {
  89             Sysout.println("No ActionEvent was generated. " + actionPerformed.get());
  90             throw new RuntimeException("Test failed!");
  91         }
  92 
  93         Sysout.println("Test passed.");
  94     }
  95 
  96     void waitTillShown(Component c) {
  97         while (true) {
  98             try {
  99                 Thread.sleep(100);
 100                 c.getLocationOnScreen();
 101                 break;
 102             } catch (InterruptedException e) {
 103                 Sysout.println("waitTillShown, non-fatal exception caught:");
 104                 e.printStackTrace();
 105             } catch (IllegalComponentStateException e) {
 106             }
 107         }
 108     }
 109 
 110     void clickOn(Component c) {
 111         Point p = c.getLocationOnScreen();
 112         Dimension d = c.getSize();
 113 
 114         if (c instanceof Frame) {
 115             robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + ((Frame)c).getInsets().top/2);
 116         } else {
 117             robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2));
 118         }
 119 
 120         robot.mousePress(InputEvent.BUTTON1_MASK);
 121         robot.delay(10);
 122         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 123         waitForIdle();
 124     }
 125 
 126     void waitForIdle() {
 127         try {
 128             Toolkit.getDefaultToolkit().sync();
 129             sun.awt.SunToolkit.flushPendingEvents();
 130             EventQueue.invokeAndWait( new Runnable() {
 131                     public void run() {} // Dummy implementation
 132                 });
 133         } catch(InterruptedException ie) {
 134             Sysout.println("waitForIdle, non-fatal exception caught:");
 135             ie.printStackTrace();
 136         } catch(InvocationTargetException ite) {
 137             Sysout.println("waitForIdle, non-fatal exception caught:");
 138             ite.printStackTrace();
 139         }
 140     }
 141 }
 142 
 143 /****************************************************
 144  Standard Test Machinery
 145  DO NOT modify anything below -- it's a standard
 146   chunk of code whose purpose is to make user
 147   interaction uniform, and thereby make it simpler
 148   to read and understand someone else's test.
 149  ****************************************************/
 150 
 151 /**
 152  This is part of the standard test machinery.
 153  It creates a dialog (with the instructions), and is the interface
 154   for sending text messages to the user.
 155  To print the instructions, send an array of strings to Sysout.createDialog
 156   WithInstructions method.  Put one line of instructions per array entry.
 157  To display a message for the tester to see, simply call Sysout.println
 158   with the string to be displayed.
 159  This mimics System.out.println but works within the test harness as well
 160   as standalone.
 161  */
 162 
 163 class Sysout
 164 {
 165     static TestDialog dialog;
 166 
 167     public static void createDialogWithInstructions( String[] instructions )
 168     {
 169         dialog = new TestDialog( new Frame(), "Instructions" );
 170         dialog.printInstructions( instructions );
 171         dialog.setVisible(true);
 172         println( "Any messages for the tester will display here." );
 173     }
 174 
 175     public static void createDialog( )
 176     {
 177         dialog = new TestDialog( new Frame(), "Instructions" );
 178         String[] defInstr = { "Instructions will appear here. ", "" } ;
 179         dialog.printInstructions( defInstr );
 180         dialog.setVisible(true);
 181         println( "Any messages for the tester will display here." );
 182     }
 183 
 184 
 185     public static void printInstructions( String[] instructions )
 186     {
 187         dialog.printInstructions( instructions );
 188     }
 189 
 190 
 191     public static void println( String messageIn )
 192     {
 193         dialog.displayMessage( messageIn );
 194     }
 195 
 196 }// Sysout  class
 197 
 198 /**
 199   This is part of the standard test machinery.  It provides a place for the
 200    test instructions to be displayed, and a place for interactive messages
 201    to the user to be displayed.
 202   To have the test instructions displayed, see Sysout.
 203   To have a message to the user be displayed, see Sysout.
 204   Do not call anything in this dialog directly.
 205   */
 206 class TestDialog extends Dialog
 207 {
 208 
 209     TextArea instructionsText;
 210     TextArea messageText;
 211     int maxStringLength = 80;
 212 
 213     //DO NOT call this directly, go through Sysout
 214     public TestDialog( Frame frame, String name )
 215     {
 216         super( frame, name );
 217         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 218         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 219         add( "North", instructionsText );
 220 
 221         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 222         add("Center", messageText);
 223 
 224         pack();
 225 
 226         setVisible(true);
 227     }// TestDialog()
 228 
 229     //DO NOT call this directly, go through Sysout
 230     public void printInstructions( String[] instructions )
 231     {
 232         //Clear out any current instructions
 233         instructionsText.setText( "" );
 234 
 235         //Go down array of instruction strings
 236 
 237         String printStr, remainingStr;
 238         for( int i=0; i < instructions.length; i++ )
 239         {
 240             //chop up each into pieces maxSringLength long
 241             remainingStr = instructions[ i ];
 242             while( remainingStr.length() > 0 )
 243             {
 244                 //if longer than max then chop off first max chars to print
 245                 if( remainingStr.length() >= maxStringLength )
 246                 {
 247                     //Try to chop on a word boundary
 248                     int posOfSpace = remainingStr.
 249                         lastIndexOf( ' ', maxStringLength - 1 );
 250 
 251                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 252 
 253                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 254                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 255                 }
 256                 //else just print
 257                 else
 258                 {
 259                     printStr = remainingStr;
 260                     remainingStr = "";
 261                 }
 262 
 263                 instructionsText.append( printStr + "\n" );
 264 
 265             }// while
 266 
 267         }// for
 268 
 269     }//printInstructions()
 270 
 271     //DO NOT call this directly, go through Sysout
 272     public void displayMessage( String messageIn )
 273     {
 274         messageText.append( messageIn + "\n" );
 275         System.out.println(messageIn);
 276     }
 277 
 278 }// TestDialog  class