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