OSDN Git Service

2005-02-17 Michael Koch <konqueror@gmx.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / Window.java
1 /* Window.java --
2    Copyright (C) 1999, 2000, 2002, 2003, 2004  Free Software Foundation
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.awt;
40
41 import java.awt.event.ComponentEvent;
42 import java.awt.event.FocusEvent;
43 import java.awt.event.WindowAdapter;
44 import java.awt.event.WindowEvent;
45 import java.awt.event.WindowFocusListener;
46 import java.awt.event.WindowListener;
47 import java.awt.event.WindowStateListener;
48 import java.awt.peer.WindowPeer;
49 import java.lang.ref.Reference;
50 import java.lang.ref.WeakReference;
51 import java.util.EventListener;
52 import java.util.Iterator;
53 import java.util.Locale;
54 import java.util.ResourceBundle;
55 import java.util.Vector;
56
57 import javax.accessibility.Accessible;
58 import javax.accessibility.AccessibleContext;
59 import javax.accessibility.AccessibleRole;
60 import javax.accessibility.AccessibleState;
61 import javax.accessibility.AccessibleStateSet;
62
63 /**
64  * This class represents a top-level window with no decorations.
65  *
66  * @author Aaron M. Renn (arenn@urbanophile.com)
67  * @author Warren Levy  (warrenl@cygnus.com)
68  */
69 public class Window extends Container implements Accessible
70 {
71   private static final long serialVersionUID = 4497834738069338734L;
72
73   // Serialized fields, from Sun's serialization spec.
74   private String warningString = null;
75   private int windowSerializedDataVersion = 0; // FIXME
76   /** @since 1.2 */
77   // private FocusManager focusMgr;  // FIXME: what is this?  
78   /** @since 1.2 */
79   private int state = 0;
80   /** @since 1.4 */
81   private boolean focusableWindowState = true;
82
83   // A list of other top-level windows owned by this window.
84   private transient Vector ownedWindows = new Vector();
85
86   private transient WindowListener windowListener;
87   private transient WindowFocusListener windowFocusListener;
88   private transient WindowStateListener windowStateListener;
89   private transient GraphicsConfiguration graphicsConfiguration;
90
91   private transient boolean shown;
92
93   private transient Component windowFocusOwner;
94   
95   protected class AccessibleAWTWindow extends AccessibleAWTContainer
96   {
97     public AccessibleRole getAccessibleRole()
98     {
99       return AccessibleRole.WINDOW;
100     }
101     
102     public AccessibleStateSet getAccessibleStateSet()
103     {
104       AccessibleStateSet states = super.getAccessibleStateSet();
105       if (isActive())
106         states.add(AccessibleState.ACTIVE);
107       return states;
108     }
109   }
110
111   /** 
112    * This (package access) constructor is used by subclasses that want
113    * to build windows that do not have parents.  Eg. toplevel
114    * application frames.  Subclasses cannot call super(null), since
115    * null is an illegal argument.
116    */
117   Window()
118   {
119     visible = false;
120     // Windows are the only Containers that default to being focus
121     // cycle roots.
122     focusCycleRoot = true;
123     setLayout(new BorderLayout());
124
125     addWindowFocusListener (new WindowAdapter ()
126       {
127         public void windowGainedFocus (WindowEvent event)
128         {
129           if (windowFocusOwner != null)
130             {
131               // FIXME: move this section and the other similar
132               // sections in Component into a separate method.
133               EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
134               synchronized (eq)
135                 {
136                   KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
137                   Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
138                   if (currentFocusOwner != null)
139                     {
140                       eq.postEvent (new FocusEvent (currentFocusOwner, FocusEvent.FOCUS_LOST,
141                                                     false, windowFocusOwner));
142                       eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED,
143                                                     false, currentFocusOwner));
144                     }
145                   else
146                     eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED, false));
147                 }
148             }
149         }
150       });
151   }
152
153   Window(GraphicsConfiguration gc)
154   {
155     this();
156     graphicsConfiguration = gc;
157   }
158
159   /**
160    * Initializes a new instance of <code>Window</code> with the specified
161    * parent.  The window will initially be invisible.
162    *
163    * @param owner The owning <code>Frame</code> of this window.
164    *
165    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
166    * is not from a screen device, or if owner is null; this exception is always
167    * thrown when GraphicsEnvironment.isHeadless returns true.
168    */
169   public Window(Frame owner)
170   {
171     this (owner, owner.getGraphicsConfiguration ());
172   }
173
174   /**
175    * Initializes a new instance of <code>Window</code> with the specified
176    * parent.  The window will initially be invisible.   
177    *
178    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
179    * is not from a screen device, or if owner is null; this exception is always
180    * thrown when GraphicsEnvironment.isHeadless returns true.
181    *
182    * @since 1.2
183    */
184   public Window(Window owner)
185   {
186     this (owner, owner.getGraphicsConfiguration ());
187   }
188   
189   /**
190    * Initializes a new instance of <code>Window</code> with the specified
191    * parent.  The window will initially be invisible.   
192    *
193    * @exception IllegalArgumentException If owner is null or if gc is not from a
194    * screen device; this exception is always thrown when
195    * GraphicsEnvironment.isHeadless returns true.
196    *
197    * @since 1.3
198    */
199   public Window(Window owner, GraphicsConfiguration gc)
200   {
201     this ();
202
203     synchronized (getTreeLock())
204       {
205         if (owner == null)
206           throw new IllegalArgumentException ("owner must not be null");
207
208         parent = owner;
209         owner.ownedWindows.add(new WeakReference(this));
210       }
211
212     // FIXME: make this text visible in the window.
213     SecurityManager s = System.getSecurityManager();
214     if (s != null && ! s.checkTopLevelWindow(this))
215       warningString = System.getProperty("awt.appletWarning");
216
217     if (gc != null
218         && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN)
219       throw new IllegalArgumentException ("gc must be from a screen device");
220
221     if (gc == null)
222       graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment()
223                                                  .getDefaultScreenDevice()
224                                                  .getDefaultConfiguration();
225     else
226       graphicsConfiguration = gc;
227   }
228
229   GraphicsConfiguration getGraphicsConfigurationImpl()
230   {
231     if (graphicsConfiguration != null)
232         return graphicsConfiguration;
233
234     return super.getGraphicsConfigurationImpl();
235   }
236
237   /**
238    * Creates the native peer for this window.
239    */
240   public void addNotify()
241   {
242     if (peer == null)
243       peer = getToolkit().createWindow(this);
244     super.addNotify();
245   }
246
247   /**
248    * Relays out this window's child components at their preferred size.
249    *
250    * @specnote pack() doesn't appear to be called internally by show(), so
251    *             we duplicate some of the functionality.
252    */
253   public void pack()
254   {
255     if (parent != null && !parent.isDisplayable())
256       parent.addNotify();
257     if (peer == null)
258       addNotify();
259
260     setSize(getPreferredSize());
261
262     validate();
263   }
264
265   /**
266    * Shows on-screen this window and any of its owned windows for whom
267    * isVisible returns true.
268    */
269   public void show()
270   {
271     if (parent != null && !parent.isDisplayable())
272       parent.addNotify();
273     if (peer == null)
274       addNotify();
275
276     // Show visible owned windows.
277     synchronized (getTreeLock())
278       {
279         Iterator e = ownedWindows.iterator();
280         while(e.hasNext())
281           {
282             Window w = (Window)(((Reference) e.next()).get());
283             if (w != null)
284               {
285                 if (w.isVisible())
286                   w.getPeer().setVisible(true);
287               }
288             else
289               // Remove null weak reference from ownedWindows.
290               // Unfortunately this can't be done in the Window's
291               // finalize method because there is no way to guarantee
292               // synchronous access to ownedWindows there.
293               e.remove();
294           }
295       }
296     validate();
297     super.show();
298     toFront();
299
300     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
301     manager.setGlobalFocusedWindow (this);
302
303     if (!shown)
304       {
305         FocusTraversalPolicy policy = getFocusTraversalPolicy ();
306         Component initialFocusOwner = null;
307
308         if (policy != null)
309           initialFocusOwner = policy.getInitialComponent (this);
310
311         if (initialFocusOwner != null)
312           initialFocusOwner.requestFocusInWindow ();
313
314         shown = true;
315       }
316   }
317
318   public void hide()
319   {
320     // Hide visible owned windows.
321     synchronized (getTreeLock ())
322       {
323         Iterator e = ownedWindows.iterator();
324         while(e.hasNext())
325           {
326             Window w = (Window)(((Reference) e.next()).get());
327             if (w != null)
328               {
329                 if (w.isVisible() && w.getPeer() != null)
330                   w.getPeer().setVisible(false);
331               }
332             else
333               e.remove();
334           }
335       }
336     super.hide();
337   }
338
339   public boolean isDisplayable()
340   {
341     if (super.isDisplayable())
342       return true;
343     return peer != null;
344   }
345
346   /**
347    * Destroys any resources associated with this window.  This includes
348    * all components in the window and all owned top-level windows.
349    */
350   public void dispose()
351   {
352     hide();
353
354     synchronized (getTreeLock ())
355       {
356         Iterator e = ownedWindows.iterator();
357         while(e.hasNext())
358           {
359             Window w = (Window)(((Reference) e.next()).get());
360             if (w != null)
361               w.dispose();
362             else
363               // Remove null weak reference from ownedWindows.
364               e.remove();
365           }
366
367         for (int i = 0; i < ncomponents; ++i)
368           component[i].removeNotify();
369         this.removeNotify();
370
371         // Post a WINDOW_CLOSED event.
372         WindowEvent we = new WindowEvent(this, WindowEvent.WINDOW_CLOSED);
373         getToolkit().getSystemEventQueue().postEvent(we);
374       }
375   }
376
377   /**
378    * Sends this window to the back so that all other windows display in
379    * front of it.
380    */
381   public void toBack()
382   {
383     if (peer != null)
384       {
385         WindowPeer wp = (WindowPeer) peer;
386         wp.toBack();
387       }
388   }
389
390   /**
391    * Brings this window to the front so that it displays in front of
392    * any other windows.
393    */
394   public void toFront()
395   {
396     if (peer != null)
397       {
398         WindowPeer wp = (WindowPeer) peer;
399         wp.toFront();
400       }
401   }
402
403   /**
404    * Returns the toolkit used to create this window.
405    *
406    * @return The toolkit used to create this window.
407    *
408    * @specnote Unlike Component.getToolkit, this implementation always 
409    *           returns the value of Toolkit.getDefaultToolkit().
410    */
411   public Toolkit getToolkit()
412   {
413     return Toolkit.getDefaultToolkit();    
414   }
415
416   /**
417    * Returns the warning string that will be displayed if this window is
418    * popped up by an unsecure applet or application.
419    *
420    * @return The unsecure window warning message.
421    */
422   public final String getWarningString()
423   {
424     return warningString;
425   }
426
427   /**
428    * Returns the locale that this window is configured for.
429    *
430    * @return The locale this window is configured for.
431    */
432   public Locale getLocale()
433   {
434     return locale == null ? Locale.getDefault() : locale;
435   }
436
437   /*
438   /** @since 1.2
439   public InputContext getInputContext()
440   {
441     // FIXME
442   }
443   */
444
445   /**
446    * Sets the cursor for this window to the specifiec cursor.
447    *
448    * @param cursor The new cursor for this window.
449    */
450   public void setCursor(Cursor cursor)
451   {
452     super.setCursor(cursor);
453   }
454
455   public Window getOwner()
456   {
457     return (Window) parent;
458   }
459
460   /** @since 1.2 */
461   public Window[] getOwnedWindows()
462   {
463     Window [] trimmedList;
464     synchronized (getTreeLock ())
465       {
466         // Windows with non-null weak references in ownedWindows.
467         Window [] validList = new Window [ownedWindows.size()];
468
469         Iterator e = ownedWindows.iterator();
470         int numValid = 0;
471         while (e.hasNext())
472           {
473             Window w = (Window)(((Reference) e.next()).get());
474             if (w != null)
475               validList[numValid++] = w;
476             else
477               // Remove null weak reference from ownedWindows.
478               e.remove();
479           }
480
481         if (numValid != validList.length)
482           {
483             trimmedList = new Window [numValid];
484             System.arraycopy (validList, 0, trimmedList, 0, numValid);
485           }
486         else
487           trimmedList = validList;
488       }
489     return trimmedList;
490   }
491
492   /**
493    * Adds the specified listener to the list of <code>WindowListeners</code>
494    * that will receive events for this window.
495    *
496    * @param listener The <code>WindowListener</code> to add.
497    */
498   public synchronized void addWindowListener(WindowListener listener)
499   {
500     windowListener = AWTEventMulticaster.add(windowListener, listener);
501   }
502
503   /**
504    * Removes the specified listener from the list of
505    * <code>WindowListeners</code> that will receive events for this window.
506    *
507    * @param listener The <code>WindowListener</code> to remove.
508    */
509   public synchronized void removeWindowListener(WindowListener listener)
510   {
511     windowListener = AWTEventMulticaster.remove(windowListener, listener);
512   }
513
514   /**
515    * Returns an array of all the window listeners registered on this window.
516    *
517    * @since 1.4
518    */
519   public synchronized WindowListener[] getWindowListeners()
520   {
521     return (WindowListener[])
522       AWTEventMulticaster.getListeners(windowListener,
523                                        WindowListener.class);
524   }
525
526   /**
527    * Returns an array of all the window focus listeners registered on this
528    * window.
529    *
530    * @since 1.4
531    */
532   public synchronized WindowFocusListener[] getWindowFocusListeners()
533   {
534     return (WindowFocusListener[])
535       AWTEventMulticaster.getListeners(windowFocusListener,
536                                        WindowFocusListener.class);
537   }
538   
539   /**
540    * Returns an array of all the window state listeners registered on this
541    * window.
542    *
543    * @since 1.4
544    */
545   public synchronized WindowStateListener[] getWindowStateListeners()
546   {
547     return (WindowStateListener[])
548       AWTEventMulticaster.getListeners(windowStateListener,
549                                        WindowStateListener.class);
550   }
551
552   /**
553    * Adds the specified listener to this window.
554    */
555   public void addWindowFocusListener (WindowFocusListener wfl)
556   {
557     windowFocusListener = AWTEventMulticaster.add (windowFocusListener, wfl);
558   }
559   
560   /**
561    * Adds the specified listener to this window.
562    *
563    * @since 1.4
564    */
565   public void addWindowStateListener (WindowStateListener wsl)
566   {
567     windowStateListener = AWTEventMulticaster.add (windowStateListener, wsl);  
568   }
569   
570   /**
571    * Removes the specified listener from this window.
572    */
573   public void removeWindowFocusListener (WindowFocusListener wfl)
574   {
575     windowFocusListener = AWTEventMulticaster.remove (windowFocusListener, wfl);
576   }
577   
578   /**
579    * Removes the specified listener from this window.
580    *
581    * @since 1.4
582    */
583   public void removeWindowStateListener (WindowStateListener wsl)
584   {
585     windowStateListener = AWTEventMulticaster.remove (windowStateListener, wsl);
586   }
587
588   /**
589    * Returns an array of all the objects currently registered as FooListeners
590    * upon this Window. FooListeners are registered using the addFooListener
591    * method.
592    *
593    * @exception ClassCastException If listenerType doesn't specify a class or
594    * interface that implements java.util.EventListener.
595    *
596    * @since 1.3
597    */
598   public EventListener[] getListeners(Class listenerType)
599   {
600     if (listenerType == WindowListener.class)
601       return getWindowListeners();
602     return super.getListeners(listenerType);
603   }
604
605   void dispatchEventImpl(AWTEvent e)
606   {
607     // Make use of event id's in order to avoid multiple instanceof tests.
608     if (e.id <= WindowEvent.WINDOW_LAST 
609         && e.id >= WindowEvent.WINDOW_FIRST
610         && (windowListener != null
611             || windowFocusListener != null
612             || windowStateListener != null
613             || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0))
614       processEvent(e);
615     else
616       super.dispatchEventImpl(e);
617   }
618
619   /**
620    * Processes the specified event for this window.  If the event is an
621    * instance of <code>WindowEvent</code>, then
622    * <code>processWindowEvent()</code> is called to process the event,
623    * otherwise the superclass version of this method is invoked.
624    *
625    * @param evt The event to process.
626    */
627   protected void processEvent(AWTEvent evt)
628   {
629     if (evt instanceof WindowEvent)
630       processWindowEvent((WindowEvent) evt);
631     else
632       super.processEvent(evt);
633   }
634
635   /**
636    * Dispatches this event to any listeners that are listening for
637    * <code>WindowEvents</code> on this window.  This method only gets
638    * invoked if it is enabled via <code>enableEvents()</code> or if
639    * a listener has been added.
640    *
641    * @param evt The event to process.
642    */
643   protected void processWindowEvent(WindowEvent evt)
644   {
645     int id = evt.getID();
646
647     if (id == WindowEvent.WINDOW_GAINED_FOCUS
648         || id == WindowEvent.WINDOW_LOST_FOCUS)
649       processWindowFocusEvent (evt);
650     else if (id == WindowEvent.WINDOW_STATE_CHANGED)
651       processWindowStateEvent (evt);
652     else
653       {
654         if (windowListener != null)
655           {
656             switch (evt.getID())
657               {
658               case WindowEvent.WINDOW_ACTIVATED:
659                 windowListener.windowActivated(evt);
660                 break;
661
662               case WindowEvent.WINDOW_CLOSED:
663                 windowListener.windowClosed(evt);
664                 break;
665
666               case WindowEvent.WINDOW_CLOSING:
667                 windowListener.windowClosing(evt);
668                 break;
669
670               case WindowEvent.WINDOW_DEACTIVATED:
671                 windowListener.windowDeactivated(evt);
672                 break;
673
674               case WindowEvent.WINDOW_DEICONIFIED:
675                 windowListener.windowDeiconified(evt);
676                 break;
677
678               case WindowEvent.WINDOW_ICONIFIED:
679                 windowListener.windowIconified(evt);
680                 break;
681
682               case WindowEvent.WINDOW_OPENED:
683                 windowListener.windowOpened(evt);
684                 break;
685
686               default:
687                 break;
688               }
689           }
690       }
691   }
692   
693   /**
694    * Identifies if this window is active.  The active window is a Frame or
695    * Dialog that has focus or owns the active window.
696    *  
697    * @return true if active, else false.
698    * @since 1.4
699    */
700   public boolean isActive()
701   {
702     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
703     return manager.getActiveWindow() == this;
704   }
705
706   /**
707    * Identifies if this window is focused.  A window is focused if it is the
708    * focus owner or it contains the focus owner.
709    * 
710    * @return true if focused, else false.
711    * @since 1.4
712    */
713   public boolean isFocused()
714   {
715     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
716     return manager.getFocusedWindow() == this;
717   }
718   
719   /**
720    * Returns the child window that has focus if this window is active.
721    * This method returns <code>null</code> if this window is not active
722    * or no children have focus.
723    *
724    * @return The component that has focus, or <code>null</code> if no
725    * component has focus.
726    */
727   public Component getFocusOwner ()
728   {
729     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
730
731     Window activeWindow = manager.getActiveWindow ();
732
733     // The currently-focused Component belongs to the active Window.
734     if (activeWindow == this)
735       return manager.getFocusOwner ();
736     else
737       return windowFocusOwner;
738   }
739
740   /**
741    * Set the focus owner for this window.  This method is used to
742    * remember which component was focused when this window lost
743    * top-level focus, so that when it regains top-level focus the same
744    * child component can be refocused.
745    *
746    * @param windowFocusOwner the component in this window that owns
747    * the focus.
748    */
749   void setFocusOwner (Component windowFocusOwner)
750   {
751     this.windowFocusOwner = windowFocusOwner;
752   }
753
754   /**
755    * Post a Java 1.0 event to the event queue.
756    *
757    * @param e The event to post.
758    *
759    * @deprecated
760    */
761   public boolean postEvent(Event e)
762   {
763     return handleEvent (e);
764   }
765
766   /**
767    * Tests whether or not this window is visible on the screen.
768    *
769    * @return <code>true</code> if this window is visible, <code>false</code>
770    * otherwise.
771    */
772   public boolean isShowing()
773   {
774     return super.isShowing();
775   }
776
777   public void setLocationRelativeTo (Component c)
778   {
779     if (c == null || !c.isShowing ())
780       {
781         int x = 0;
782         int y = 0;
783
784         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
785         Point center = ge.getCenterPoint ();
786         x = center.x - (width / 2);
787         y = center.y - (height / 2);
788         setLocation (x, y);
789       }
790     // FIXME: handle case where component is non-null.
791   }
792
793   /**
794    * @since 1.2
795    *
796    * @deprecated
797    */
798   public void applyResourceBundle(ResourceBundle rb)
799   {
800     throw new Error ("Not implemented");
801   }
802
803   /**
804    * @since 1.2
805    *
806    * @deprecated
807    */
808   public void applyResourceBundle(String rbName)
809   {
810     ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(),
811       ClassLoader.getSystemClassLoader());
812     if (rb != null)
813       applyResourceBundle(rb);    
814   }
815
816   /**
817    * Gets the AccessibleContext associated with this <code>Window</code>.
818    * The context is created, if necessary.
819    *
820    * @return the associated context
821    */
822   public AccessibleContext getAccessibleContext()
823   {
824     /* Create the context if this is the first request */
825     if (accessibleContext == null)
826       accessibleContext = new AccessibleAWTWindow();
827     return accessibleContext;
828   }
829
830   /** 
831    * Get graphics configuration.  The implementation for Window will
832    * not ask any parent containers, since Window is a toplevel
833    * window and not actually embedded in the parent component.
834    */
835   public GraphicsConfiguration getGraphicsConfiguration()
836   {
837     if (graphicsConfiguration != null) return graphicsConfiguration;
838     if (peer != null) return peer.getGraphicsConfiguration();
839     return null;
840   }
841
842   protected void processWindowFocusEvent(WindowEvent event)
843   {
844     if (windowFocusListener != null)
845       {
846         switch (event.getID ())
847           {
848           case WindowEvent.WINDOW_GAINED_FOCUS:
849             windowFocusListener.windowGainedFocus (event);
850             break;
851             
852           case WindowEvent.WINDOW_LOST_FOCUS:
853             windowFocusListener.windowLostFocus (event);
854             break;
855             
856           default:
857             break;
858           }
859       }
860   }
861   
862   /**
863    * @since 1.4
864    */
865   protected void processWindowStateEvent(WindowEvent event)
866   {
867     if (windowStateListener != null
868         && event.getID () == WindowEvent.WINDOW_STATE_CHANGED)
869       windowStateListener.windowStateChanged (event);
870   }
871
872   /**
873    * Returns whether this <code>Window</code> can get the focus or not.
874    *
875    * @since 1.4
876    */
877   public final boolean isFocusableWindow ()
878   {
879     if (getFocusableWindowState () == false)
880       return false;
881
882     if (this instanceof Dialog
883         || this instanceof Frame)
884       return true;
885
886     // FIXME: Implement more possible cases for returning true.
887
888     return false;
889   }
890   
891   /**
892    * Returns the value of the focusableWindowState property.
893    * 
894    * @since 1.4
895    */
896   public boolean getFocusableWindowState ()
897   {
898     return focusableWindowState;
899   }
900
901   /**
902    * Sets the value of the focusableWindowState property.
903    * 
904    * @since 1.4
905    */
906   public void setFocusableWindowState (boolean focusableWindowState)
907   {
908     this.focusableWindowState = focusableWindowState;
909   }
910
911   // setBoundsCallback is needed so that when a user moves a window,
912   // the Window's location can be updated without calling the peer's
913   // setBounds method.  When a user moves a window the peer window's
914   // location is updated automatically and the windowing system sends
915   // a message back to the application informing it of its updated
916   // dimensions.  We must update the AWT Window class with these new
917   // dimensions.  But we don't want to call the peer's setBounds
918   // method, because the peer's dimensions have already been updated.
919   // (Under X, having this method prevents Configure event loops when
920   // moving windows: Component.setBounds -> peer.setBounds ->
921   // postConfigureEvent -> Component.setBounds -> ...  In some cases
922   // Configure event loops cause windows to jitter back and forth
923   // continuously).
924   void setBoundsCallback (int x, int y, int w, int h)
925   {
926     if (this.x == x && this.y == y && width == w && height == h)
927       return;
928     invalidate();
929     boolean resized = width != w || height != h;
930     boolean moved = this.x != x || this.y != y;
931     this.x = x;
932     this.y = y;
933     width = w;
934     height = h;
935     if (resized && isShowing ())
936       {
937         ComponentEvent ce =
938           new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED);
939         getToolkit().getSystemEventQueue().postEvent(ce);
940       }
941     if (moved && isShowing ())
942       {
943         ComponentEvent ce =
944           new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED);
945         getToolkit().getSystemEventQueue().postEvent(ce);
946       }
947   }
948 }