1/* 2 * Copyright (c) 2007, 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 */ 23 24/* 25 @test 26 @bug 6565779 8168292 27 @library ../../regtesthelpers 28 @compile DragEventSource.java 29 @summary Exception if source of some event is TrayIcon 30 @author Andrei Dmitriev: area=awt.tray 31 @run main/manual/othervm -Dsun.awt.exception.handler=DragEventSource DragEventSource 32*/ 33 34/** 35 * DragEventSource.java 36 * 37 * summary: an exception happen if the DRAG event has a TrayIcon 38 * instance as source. 39 */ 40 41import java.awt.Button; 42import java.awt.Dialog; 43import java.awt.FileDialog; 44import java.awt.FlowLayout; 45import java.awt.Frame; 46import java.awt.Image; 47import java.awt.Panel; 48import java.awt.SystemTray; 49import java.awt.TextArea; 50import java.awt.TrayIcon; 51import java.awt.event.ActionEvent; 52import java.awt.event.ActionListener; 53import java.awt.image.BufferedImage; 54 55public class DragEventSource 56{ 57 static Frame frame = new Frame("Test frame"); 58 static Button b1 = new Button("Open file dialog"); 59 static SystemTray tray = null; 60 static TrayIcon icon = null; 61 static Image img = null; 62 static FileDialog fd = null; 63 64 //a method to transfer throwables to the user 65 public void handle(Throwable e){ 66 Sysout.println("HANDLED BY THE CUSTOM HANDLER !!!!!!"+e); 67 } 68 69 static class ActionHandler implements ActionListener { 70 public void actionPerformed (ActionEvent ae) { 71 FileDialog fd = new FileDialog (frame, "Image Selector", FileDialog.LOAD); 72 fd.setVisible(true); 73 } 74 } 75 76 private static void init() { 77 78 boolean isSupported = SystemTray.isSupported(); 79 System.out.println("is SysTray Supported: " + isSupported); 80 81 if (!isSupported) { 82 String[] instructions = 83 { 84 "The test cannot be run because SystemTray is not supported.", 85 "Simply press PASS button." 86 }; 87 Sysout.createDialog( ); 88 Sysout.printInstructions( instructions ); 89 return; 90 } 91 92 String[] instructions = 93 { 94 "Click 'Open file dialog' button. FileDialog should appear.", 95 "Using left mouse button,", 96 "Drag the mouse from the Tray icon to FileDialog.", 97 "If exception is thrown, the test fails.", 98 "Otherwise, pass." 99 }; 100 101 Sysout.createDialog( ); 102 Sysout.printInstructions( instructions ); 103 104 frame.setLayout(new FlowLayout()); 105 tray = SystemTray.getSystemTray(); 106 107 108 TrayIcon icons[] = tray.getTrayIcons(); 109 System.out.println(icons.length); 110 111 b1.addActionListener(new ActionHandler()); 112 113 icon = new TrayIcon(new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB)); 114 icon.setImageAutoSize(true); 115 116 try { 117 tray.add(icon); 118 } catch (Exception e) { 119 e.printStackTrace(); 120 } 121 122 frame.add(b1); 123 124 frame.setSize(600, 200); 125 frame.setVisible(true); 126 }//End init() 127 128 129 130 /***************************************************** 131 * Standard Test Machinery Section 132 * DO NOT modify anything in this section -- it's a 133 * standard chunk of code which has all of the 134 * synchronisation necessary for the test harness. 135 * By keeping it the same in all tests, it is easier 136 * to read and understand someone else's test, as 137 * well as insuring that all tests behave correctly 138 * with the test harness. 139 * There is a section following this for test-defined 140 * classes 141 ******************************************************/ 142 private static boolean theTestPassed = false; 143 private static boolean testGeneratedInterrupt = false; 144 private static String failureMessage = ""; 145 146 private static Thread mainThread = null; 147 148 private static int sleepTime = 300000; 149 150 public static void main( String args[] ) throws InterruptedException 151 { 152 mainThread = Thread.currentThread(); 153 154 try 155 { 156 init(); 157 } 158 catch( TestPassedException e ) 159 { 160 //The test passed, so just return from main and harness will 161 // interepret this return as a pass 162 return; 163 } 164 //At this point, neither test passed nor test failed has been 165 // called -- either would have thrown an exception and ended the 166 // test, so we know we have multiple threads. 167 168 //Test involves other threads, so sleep and wait for them to 169 // called pass() or fail() 170 try 171 { 172 Thread.sleep( sleepTime ); 173 //Timed out, so fail the test 174 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 175 } 176 catch (InterruptedException e) 177 { 178 if( ! testGeneratedInterrupt ) throw e; 179 180 //reset flag in case hit this code more than once for some reason (just safety) 181 testGeneratedInterrupt = false; 182 if ( theTestPassed == false ) 183 { 184 throw new RuntimeException( failureMessage ); 185 } 186 } 187 188 }//main 189 190 public static synchronized void setTimeoutTo( int seconds ) 191 { 192 sleepTime = seconds * 1000; 193 } 194 195 public static synchronized void pass() 196 { 197 Sysout.println( "The test passed." ); 198 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 199 //first check if this is executing in main thread 200 if ( mainThread == Thread.currentThread() ) 201 { 202 //Still in the main thread, so set the flag just for kicks, 203 // and throw a test passed exception which will be caught 204 // and end the test. 205 theTestPassed = true; 206 throw new TestPassedException(); 207 } 208 //pass was called from a different thread, so set the flag and interrupt 209 // the main thead. 210 theTestPassed = true; 211 testGeneratedInterrupt = true; 212 mainThread.interrupt(); 213 }//pass() 214 215 public static synchronized void fail() 216 { 217 //test writer didn't specify why test failed, so give generic 218 fail( "it just plain failed! :-)" ); 219 } 220 221 public static synchronized void fail( String whyFailed ) 222 { 223 Sysout.println( "The test failed: " + whyFailed ); 224 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 225 //check if this called from main thread 226 if ( mainThread == Thread.currentThread() ) 227 { 228 //If main thread, fail now 'cause not sleeping 229 throw new RuntimeException( whyFailed ); 230 } 231 theTestPassed = false; 232 testGeneratedInterrupt = true; 233 failureMessage = whyFailed; 234 mainThread.interrupt(); 235 }//fail() 236 237}// class DragEventSource 238 239//This exception is used to exit from any level of call nesting 240// when it's determined that the test has passed, and immediately 241// end the test. 242 243class TestPassedException extends RuntimeException 244{ 245} 246 247//*********** End Standard Test Machinery Section ********** 248 249 250//************ Begin classes defined for the test **************** 251 252// make listeners in a class defined here, and instantiate them in init() 253 254/* Example of a class which may be written as part of a test 255class NewClass implements anInterface 256 { 257 static int newVar = 0; 258 259 public void eventDispatched(AWTEvent e) 260 { 261 //Counting events to see if we get enough 262 eventCount++; 263 264 if( eventCount == 20 ) 265 { 266 //got enough events, so pass 267 268 ManualMainTest.pass(); 269 } 270 else if( tries == 20 ) 271 { 272 //tried too many times without getting enough events so fail 273 274 ManualMainTest.fail(); 275 } 276 277 }// eventDispatched() 278 279 }// NewClass class 280 281*/ 282 283 284//************** End classes defined for the test ******************* 285 286 287 288 289/**************************************************** 290 Standard Test Machinery 291 DO NOT modify anything below -- it's a standard 292 chunk of code whose purpose is to make user 293 interaction uniform, and thereby make it simpler 294 to read and understand someone else's test. 295 ****************************************************/ 296 297/** 298 This is part of the standard test machinery. 299 It creates a dialog (with the instructions), and is the interface 300 for sending text messages to the user. 301 To print the instructions, send an array of strings to Sysout.createDialog 302 WithInstructions method. Put one line of instructions per array entry. 303 To display a message for the tester to see, simply call Sysout.println 304 with the string to be displayed. 305 This mimics System.out.println but works within the test harness as well 306 as standalone. 307 */ 308 309class Sysout 310{ 311 private static TestDialog dialog; 312 313 public static void createDialogWithInstructions( String[] instructions ) 314 { 315 dialog = new TestDialog( new Frame(), "Instructions" ); 316 dialog.printInstructions( instructions ); 317 dialog.setVisible(true); 318 println( "Any messages for the tester will display here." ); 319 } 320 321 public static void createDialog( ) 322 { 323 dialog = new TestDialog( new Frame(), "Instructions" ); 324 String[] defInstr = { "Instructions will appear here. ", "" } ; 325 dialog.printInstructions( defInstr ); 326 dialog.setVisible(true); 327 println( "Any messages for the tester will display here." ); 328 } 329 330 331 public static void printInstructions( String[] instructions ) 332 { 333 dialog.printInstructions( instructions ); 334 } 335 336 337 public static void println( String messageIn ) 338 { 339 dialog.displayMessage( messageIn ); 340 } 341 342}// Sysout class 343 344/** 345 This is part of the standard test machinery. It provides a place for the 346 test instructions to be displayed, and a place for interactive messages 347 to the user to be displayed. 348 To have the test instructions displayed, see Sysout. 349 To have a message to the user be displayed, see Sysout. 350 Do not call anything in this dialog directly. 351 */ 352class TestDialog extends Dialog implements ActionListener 353{ 354 355 TextArea instructionsText; 356 TextArea messageText; 357 int maxStringLength = 80; 358 Panel buttonP = new Panel(); 359 Button passB = new Button( "pass" ); 360 Button failB = new Button( "fail" ); 361 362 //DO NOT call this directly, go through Sysout 363 public TestDialog( Frame frame, String name ) 364 { 365 super( frame, name ); 366 int scrollBoth = TextArea.SCROLLBARS_BOTH; 367 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 368 add( "North", instructionsText ); 369 370 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 371 add("Center", messageText); 372 373 passB = new Button( "pass" ); 374 passB.setActionCommand( "pass" ); 375 passB.addActionListener( this ); 376 buttonP.add( "East", passB ); 377 378 failB = new Button( "fail" ); 379 failB.setActionCommand( "fail" ); 380 failB.addActionListener( this ); 381 buttonP.add( "West", failB ); 382 383 add( "South", buttonP ); 384 pack(); 385 386 setVisible(true); 387 }// TestDialog() 388 389 //DO NOT call this directly, go through Sysout 390 public void printInstructions( String[] instructions ) 391 { 392 //Clear out any current instructions 393 instructionsText.setText( "" ); 394 395 //Go down array of instruction strings 396 397 String printStr, remainingStr; 398 for( int i=0; i < instructions.length; i++ ) 399 { 400 //chop up each into pieces maxSringLength long 401 remainingStr = instructions[ i ]; 402 while( remainingStr.length() > 0 ) 403 { 404 //if longer than max then chop off first max chars to print 405 if( remainingStr.length() >= maxStringLength ) 406 { 407 //Try to chop on a word boundary 408 int posOfSpace = remainingStr. 409 lastIndexOf( ' ', maxStringLength - 1 ); 410 411 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 412 413 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 414 remainingStr = remainingStr.substring( posOfSpace + 1 ); 415 } 416 //else just print 417 else 418 { 419 printStr = remainingStr; 420 remainingStr = ""; 421 } 422 423 instructionsText.append( printStr + "\n" ); 424 425 }// while 426 427 }// for 428 429 }//printInstructions() 430 431 //DO NOT call this directly, go through Sysout 432 public void displayMessage( String messageIn ) 433 { 434 messageText.append( messageIn + "\n" ); 435 System.out.println(messageIn); 436 } 437 438 //catch presses of the passed and failed buttons. 439 //simply call the standard pass() or fail() static methods of 440 //ManualMainTest 441 public void actionPerformed( ActionEvent e ) 442 { 443 if( e.getActionCommand() == "pass" ) 444 { 445 DragEventSource.pass(); 446 } 447 else 448 { 449 DragEventSource.fail(); 450 } 451 } 452 453}// TestDialog class 454