KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > groboutils > uicapture > v1 > VirtualWindow


1 /*
2  * @(#)VirtualWindow.java
3  *
4  * Copyright (C) 2002-2003 Matt Albrecht
5  * groboclown@users.sourceforge.net
6  * http://groboutils.sourceforge.net
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  */

26
27 package net.sourceforge.groboutils.uicapture.v1;
28
29 import java.awt.Robot JavaDoc;
30 import java.awt.Frame JavaDoc;
31 import java.awt.Rectangle JavaDoc;
32 import java.awt.image.BufferedImage JavaDoc;
33 import java.awt.event.KeyListener JavaDoc;
34 import java.awt.event.MouseListener JavaDoc;
35 import java.awt.event.MouseMotionListener JavaDoc;
36 import java.awt.event.MouseWheelListener JavaDoc;
37 import java.awt.event.MouseEvent JavaDoc;
38 import java.awt.event.KeyEvent JavaDoc;
39 import java.awt.event.MouseWheelEvent JavaDoc;
40
41 import java.util.LinkedList JavaDoc;
42 import java.util.Iterator JavaDoc;
43
44 import net.sourceforge.groboutils.uicapture.v1.event.ICaptureListener;
45 import net.sourceforge.groboutils.uicapture.v1.event.CaptureEvent;
46 import net.sourceforge.groboutils.uicapture.v1.event.KeyPressedCaptureEvent;
47 import net.sourceforge.groboutils.uicapture.v1.event.KeyReleasedCaptureEvent;
48 import net.sourceforge.groboutils.uicapture.v1.event.MousePressedCaptureEvent;
49 import net.sourceforge.groboutils.uicapture.v1.event.MouseReleasedCaptureEvent;
50 import net.sourceforge.groboutils.uicapture.v1.event.MouseMovedCaptureEvent;
51 import net.sourceforge.groboutils.uicapture.v1.event.MouseWheelCaptureEvent;
52 import net.sourceforge.groboutils.uicapture.v1.event.IAllowCapturePassThroughListener;
53
54 /**
55  * A window which covers the whole screen, and does not paint in the background.
56  * It captures keyboard and mouse events, and sends them to both all registered
57  * listeners, and to the underlying GUI as well. This transparent window is
58  * similar to the "glass pane" concept in Swing JFrames.
59  * <P>
60  * For the moment, there is no way for listeners to prevent an event from
61  * being passed to the underlying UI. This needs to be changed.
62  * <P>
63  * WARNING: if the screen size is to resize, then this will not work correctly.
64  *
65  * @author Matt Albrecht <a HREF="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
66  * @since Jan 4, 2002
67  * @version Mar 13, 2002
68  */

69 public class VirtualWindow
70         implements KeyListener JavaDoc, MouseListener JavaDoc, MouseMotionListener JavaDoc,
71             MouseWheelListener JavaDoc
72 {
73     //-------------------------------------------------------------------------
74
// Private fields
75

76     private LinkedList JavaDoc captureListeners = new LinkedList JavaDoc();
77     private Robot JavaDoc robot = null;
78     private VirtualWindowUI window = null;
79     private boolean enableGlass = true;
80     private Frame JavaDoc owningFrame = null;
81     
82     private static final String JavaDoc DEFAULT_TITLE = "UI Capture";
83     
84     //-------------------------------------------------------------------------
85
// Constructors
86

87     
88     /**
89      * Create a new VirtualWindow, with the glass enabled.
90      *
91      * @exception java.awt.AWTException thrown if a Robot is not supported
92      * in the current JDK implementation.
93      */

94     public VirtualWindow()
95             throws java.awt.AWTException JavaDoc
96     {
97         this( null, true );
98     }
99     
100     
101     /**
102      * Specify the initial enabled state of the window.
103      *
104      * @param enable set to the initial glass pane state.
105      * @exception java.awt.AWTException thrown if a Robot is not supported
106      * in the current JDK implementation.
107      */

108     public VirtualWindow( String JavaDoc title, boolean enable )
109             throws java.awt.AWTException JavaDoc
110     {
111         if (title == null)
112         {
113             title = DEFAULT_TITLE;
114         }
115         this.owningFrame = new Frame JavaDoc( title );
116         this.owningFrame.setSize( 0, 0 );
117         // this.owningFrame.show();
118
// this.owningFrame.hide();
119
this.window = new VirtualWindowUI( this.owningFrame );
120         this.robot = new Robot JavaDoc();
121         
122         this.window.addKeyListener( this );
123         this.window.addMouseListener( this );
124         this.window.addMouseMotionListener( this );
125         this.window.addMouseWheelListener( this );
126         
127         update();
128
129         setGlassEnabled( enable );
130     }
131     
132
133
134     //-------------------------------------------------------------------------
135
// Public methods
136

137     
138     /**
139      * Close out all inner instances and shut down the UI
140      */

141     public void dispose()
142     {
143         this.window.removeKeyListener( this );
144         this.window.removeMouseListener( this );
145         this.window.removeMouseMotionListener( this );
146         this.window.removeMouseWheelListener( this );
147         
148         this.window.dispose();
149         this.owningFrame.dispose();
150         this.captureListeners.clear();
151         this.robot = null;
152         this.window = null;
153     }
154     
155     
156     /**
157      *
158      * @return the inner Window reference.
159      */

160     public VirtualWindowUI getWindow()
161     {
162         return this.window;
163     }
164     
165     
166     /**
167      * Sets the inner state for displaying the glass pane. If the pane is
168      * enabled, then the glass pane will attempt to maximize itself and
169      * keep itself on the foreground at all costs.
170      *
171      * @param on <tt>true</tt> if the glass pane is enabled (active and
172      * intercepting events), or <tt>false</tt> if is disabled.
173      */

174     public synchronized void setGlassEnabled( boolean on )
175     {
176         this.enableGlass = on;
177         this.window.setGlassEnabled( on );
178     }
179     
180     
181     /**
182      * Retrieves the current glass enabled state.
183      *
184      * @return <tt>true</tt> if the glass pane is enabled (active and
185      * intercepting events), or <tt>false</tt> if is disabled.
186      */

187     public boolean isGlassEnabled()
188     {
189         return this.enableGlass;
190     }
191     
192     
193     /**
194      * Simulates the given captured event. This minimizes the glass window,
195      * performs the event with the Robot, and restores the glass window if
196      * the glass pane is enabled.
197      *
198      * @param ce the event to simulate.
199      */

200     public synchronized void simulateEvent( CaptureEvent ce )
201     {
202         hide();
203
204         // ensure that the window is restored, no matter the exception.
205
try
206         {
207             ce.performEvent( this.robot );
208         }
209         finally
210         {
211             show();
212         }
213     }
214     
215     
216     /**
217      * Sleeps for the specified number of milliseconds. This is passed
218      * directly through to the underlying Robot.
219      *
220      * @param ms Time to sleep in milliseconds.
221      * @exception IllegalArgumentException thrown by Robot if <tt>ms</tt> is
222      * not between 0 and 60,000, inclusive.
223      */

224     public void delay( int ms )
225     {
226         this.robot.delay( ms );
227     }
228     
229     
230     /**
231      * Waits until all events currently on the event queue have been processed.
232      * This is passed directly through to the underlying Robot.
233      */

234     public void waitForIdle()
235     {
236         this.robot.waitForIdle();
237     }
238     
239     
240     /**
241      * Scrapes the current screen into a BufferedImage the same size as the
242      * window.
243      *
244      * @return the captured screen image.
245      */

246     public BufferedImage JavaDoc createScreenScrape()
247     {
248         return createScreenScrape( this.window.getCoveredScreen() );
249     }
250     
251     
252     /**
253      * Scrapes the current screen into a BufferedImage from the given area
254      * on the screen. This is passed directly to the underlying Robot.
255      *
256      * @return the captured screen image.
257      */

258     public BufferedImage JavaDoc createScreenScrape( Rectangle JavaDoc bounds )
259     {
260         // check bounds against the window's bounds
261
if (bounds == null ||
262             !this.window.getCoveredScreen().contains( bounds ))
263         {
264             throw new IllegalArgumentException JavaDoc("Bounds "+bounds+
265                 " is not within the screen dimension.");
266         }
267         
268         // ensure the window is hidden, to get the current screen image,
269
// then restore the window, no matter the thrown exceptions.
270
hide();
271         
272         try
273         {
274             return this.robot.createScreenCapture( bounds );
275         }
276         finally
277         {
278             show();
279         }
280     }
281     
282     
283     /**
284      * Adds an <tt>ICaptureListener</tt> to the list of recipients of input
285      * events. If the given listener is <tt>null</tt>, then the request is
286      * ignored.
287      *
288      * @param cl the listener to add.
289      */

290     public void addCaptureListener( ICaptureListener cl )
291     {
292         if (cl != null)
293         {
294             this.captureListeners.add( cl );
295         }
296     }
297     
298     
299     /**
300      * Removes the given <tt>ICaptureListener</tt> from the inner list of
301      * input events recipients. If the given listener is <tt>null</tt> or
302      * not registered, then the request is ignored.
303      *
304      * @param cl the listener to remove.
305      */

306     public void removeCaptureListener( ICaptureListener cl )
307     {
308         if (cl != null)
309         {
310             this.captureListeners.remove( cl );
311         }
312     }
313     
314     
315     /**
316      * Hides the glass pane, and stops all input event capturing. This is
317      * only executed if the glass is enabled, and has no effect on the
318      * enabled state of the glass.
319      */

320     public void hide()
321     {
322         if (this.enableGlass)
323         {
324             this.window.hide();
325         }
326     }
327     
328     
329     /**
330      * Shows the glass pane, and continues all input event capturing. This is
331      * only executed if the glass is enabled, and has no effect on the
332      * enabled state of the glass.
333      */

334     public void show()
335     {
336         if (this.enableGlass)
337         {
338             this.window.show();
339         }
340     }
341     
342     
343     /**
344      * Updates the background image.
345      */

346     public void update()
347     {
348         this.window.setBackground( createScreenScrape() );
349     }
350     
351     
352     //-------------------------------------------------------------------------
353
// Event methods
354

355     
356     
357     /**
358      * @see java.awt.event.MouseWheelListener
359      */

360     public void mouseWheelMoved( MouseWheelEvent JavaDoc me )
361     {
362         MouseWheelCaptureEvent ce = new MouseWheelCaptureEvent( me );
363         Iterator JavaDoc iter = getCaptureListeners();
364         boolean allow = true;
365         while (iter.hasNext())
366         {
367             ICaptureListener icl = (ICaptureListener)iter.next();
368             if (icl instanceof IAllowCapturePassThroughListener)
369             {
370                 if (!((IAllowCapturePassThroughListener)icl).
371                     allowMouseWheelMoved( ce ))
372                 {
373                     allow = false;
374                 }
375             }
376             icl.mouseWheelMoved( ce );
377         }
378         if (allow)
379         {
380             simulateEvent( ce );
381         }
382     }
383     
384     
385     /**
386      * @see java.awt.event.MouseMotionListener
387      */

388     public void mouseDragged( MouseEvent JavaDoc me )
389     {
390         // ignore this method
391
}
392     
393     
394     /**
395      * @see java.awt.event.MouseMotionListener
396      */

397     public void mouseMoved( MouseEvent JavaDoc me )
398     {
399         MouseMovedCaptureEvent ce = new MouseMovedCaptureEvent( me );
400         
401         // do not need to simulate event: the mouse already moved.
402
// simulateEvent( ce );
403

404         Iterator JavaDoc iter = getCaptureListeners();
405         while (iter.hasNext())
406         {
407             ((ICaptureListener)iter.next()).mouseMoved( ce );
408         }
409     }
410     
411     
412     /**
413      * @see java.awt.event.MouseListener
414      */

415     public void mousePressed( MouseEvent JavaDoc me )
416     {
417         MousePressedCaptureEvent ce = new MousePressedCaptureEvent( me );
418         Iterator JavaDoc iter = getCaptureListeners();
419         boolean allow = true;
420         while (iter.hasNext())
421         {
422             ICaptureListener icl = (ICaptureListener)iter.next();
423             if (icl instanceof IAllowCapturePassThroughListener)
424             {
425                 if (!((IAllowCapturePassThroughListener)icl).
426                     allowMousePressed( ce ))
427                 {
428                     allow = false;
429                 }
430             }
431             icl.mousePressed( ce );
432         }
433         if (allow)
434         {
435             simulateEvent( ce );
436         }
437     }
438     
439     
440     /**
441      * @see java.awt.event.MouseListener
442      */

443     public void mouseReleased( MouseEvent JavaDoc me )
444     {
445         MouseReleasedCaptureEvent ce = new MouseReleasedCaptureEvent( me );
446         Iterator JavaDoc iter = getCaptureListeners();
447         boolean allow = true;
448         while (iter.hasNext())
449         {
450             ICaptureListener icl = (ICaptureListener)iter.next();
451             if (icl instanceof IAllowCapturePassThroughListener)
452             {
453                 if (!((IAllowCapturePassThroughListener)icl).
454                     allowMouseReleased( ce ))
455                 {
456                     allow = false;
457                 }
458             }
459             icl.mouseReleased( ce );
460         }
461         if (allow)
462         {
463             simulateEvent( ce );
464         }
465     }
466     
467     
468     
469     /**
470      * @see java.awt.event.MouseListener
471      */

472     public void mouseClicked( MouseEvent JavaDoc me )
473     {
474         // ignore this method
475
}
476     
477     
478     
479     /**
480      * @see java.awt.event.MouseListener
481      */

482     public void mouseEntered( MouseEvent JavaDoc me )
483     {
484         // ignore this method
485
}
486     
487     
488     
489     /**
490      * @see java.awt.event.MouseListener
491      */

492     public void mouseExited( MouseEvent JavaDoc me )
493     {
494         // ignore this method
495
}
496     
497     
498     
499     /**
500      * @see java.awt.event.KeyListener
501      */

502     public void keyTyped( KeyEvent JavaDoc me )
503     {
504         // ignore this method
505
}
506     
507     
508     /**
509      * @see java.awt.event.KeyListener
510      */

511     public void keyPressed( KeyEvent JavaDoc ke )
512     {
513         KeyPressedCaptureEvent ce = new KeyPressedCaptureEvent( ke );
514         Iterator JavaDoc iter = getCaptureListeners();
515         boolean allow = true;
516         while (iter.hasNext())
517         {
518             ICaptureListener icl = (ICaptureListener)iter.next();
519             if (icl instanceof IAllowCapturePassThroughListener)
520             {
521                 if (!((IAllowCapturePassThroughListener)icl).
522                     allowKeyPressed( ce ))
523                 {
524                     allow = false;
525                 }
526             }
527             icl.keyPressed( ce );
528         }
529         if (allow)
530         {
531             simulateEvent( ce );
532         }
533     }
534     
535     
536     /**
537      * @see java.awt.event.KeyListener
538      */

539     public void keyReleased( KeyEvent JavaDoc ke )
540     {
541         KeyReleasedCaptureEvent ce = new KeyReleasedCaptureEvent( ke );
542         Iterator JavaDoc iter = getCaptureListeners();
543         boolean allow = true;
544         while (iter.hasNext())
545         {
546             ICaptureListener icl = (ICaptureListener)iter.next();
547             if (icl instanceof IAllowCapturePassThroughListener)
548             {
549                 if (!((IAllowCapturePassThroughListener)icl).
550                     allowKeyReleased( ce ))
551                 {
552                     allow = false;
553                 }
554             }
555             icl.keyReleased( ce );
556         }
557         if (allow)
558         {
559             simulateEvent( ce );
560         }
561     }
562     
563     
564     
565     //-------------------------------------------------------------------------
566
// Protected methods
567

568     
569     /**
570      * Returns a list of all the current ICaptureListeners.
571      *
572      * @return an iterator of the listeners.
573      */

574     protected Iterator JavaDoc getCaptureListeners()
575     {
576         return this.captureListeners.iterator();
577     }
578 }
579
580
Popular Tags