OSDN Git Service

libjava/
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / awt / Window.java
1 /* Window.java --
2    Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005  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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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.WindowEvent;
43 import java.awt.event.WindowFocusListener;
44 import java.awt.event.WindowListener;
45 import java.awt.event.WindowStateListener;
46 import java.awt.image.BufferStrategy;
47 import java.awt.peer.WindowPeer;
48 import java.lang.ref.Reference;
49 import java.lang.ref.WeakReference;
50 import java.util.EventListener;
51 import java.util.Iterator;
52 import java.util.Locale;
53 import java.util.ResourceBundle;
54 import java.util.Vector;
55
56 import javax.accessibility.Accessible;
57 import javax.accessibility.AccessibleContext;
58 import javax.accessibility.AccessibleRole;
59 import javax.accessibility.AccessibleState;
60 import javax.accessibility.AccessibleStateSet;
61
62 /**
63  * This class represents a top-level window with no decorations.
64  *
65  * @author Aaron M. Renn (arenn@urbanophile.com)
66  * @author Warren Levy  (warrenl@cygnus.com)
67  */
68 public class Window extends Container implements Accessible
69 {
70   private static final long serialVersionUID = 4497834738069338734L;
71
72   // Serialized fields, from Sun's serialization spec.
73   private String warningString = null;
74   private int windowSerializedDataVersion = 0; // FIXME
75   /** @since 1.2 */
76   // private FocusManager focusMgr;  // FIXME: what is this?  
77   /** @since 1.2 */
78   private int state = 0;
79   /** @since 1.4 */
80   private boolean focusableWindowState = true;
81   /** @since 1.5 */
82   private boolean alwaysOnTop = false;
83
84   // A list of other top-level windows owned by this window.
85   private transient Vector ownedWindows = new Vector();
86
87   private transient WindowListener windowListener;
88   private transient WindowFocusListener windowFocusListener;
89   private transient WindowStateListener windowStateListener;
90
91   private transient boolean shown;
92
93   // This is package-private to avoid an accessor method.
94   transient Component windowFocusOwner;
95   
96   /*
97    * The number used to generate the name returned by getName.
98    */
99   private static transient long next_window_number;
100
101   protected class AccessibleAWTWindow extends AccessibleAWTContainer
102   {
103     private static final long serialVersionUID = 4215068635060671780L;
104
105     public AccessibleRole getAccessibleRole()
106     {
107       return AccessibleRole.WINDOW;
108     }
109     
110     public AccessibleStateSet getAccessibleStateSet()
111     {
112       AccessibleStateSet states = super.getAccessibleStateSet();
113       if (isActive())
114         states.add(AccessibleState.ACTIVE);
115       return states;
116     }
117   }
118
119   /** 
120    * This (package access) constructor is used by subclasses that want
121    * to build windows that do not have parents.  Eg. toplevel
122    * application frames.  Subclasses cannot call super(null), since
123    * null is an illegal argument.
124    */
125   Window()
126   {
127     visible = false;
128     // Windows are the only Containers that default to being focus
129     // cycle roots.
130     focusCycleRoot = true;
131     setLayout(new BorderLayout());
132     
133     GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
134     graphicsConfig = g.getDefaultScreenDevice().getDefaultConfiguration();
135   }
136
137   Window(GraphicsConfiguration gc)
138   {
139     this();
140     graphicsConfig = gc;
141   }
142
143   /**
144    * Initializes a new instance of <code>Window</code> with the specified
145    * parent.  The window will initially be invisible.
146    *
147    * @param owner The owning <code>Frame</code> of this window.
148    *
149    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
150    * is not from a screen device, or if owner is null; this exception is always
151    * thrown when GraphicsEnvironment.isHeadless returns true.
152    */
153   public Window(Frame owner)
154   {
155     this (owner, owner.getGraphicsConfiguration ());
156   }
157
158   /**
159    * Initializes a new instance of <code>Window</code> with the specified
160    * parent.  The window will initially be invisible.   
161    *
162    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
163    * is not from a screen device, or if owner is null; this exception is always
164    * thrown when GraphicsEnvironment.isHeadless returns true.
165    *
166    * @since 1.2
167    */
168   public Window(Window owner)
169   {
170     this (owner, owner.getGraphicsConfiguration ());
171   }
172   
173   /**
174    * Initializes a new instance of <code>Window</code> with the specified
175    * parent.  The window will initially be invisible.   
176    *
177    * @exception IllegalArgumentException If owner is null or if gc is not from a
178    * screen device; this exception is always thrown when
179    * GraphicsEnvironment.isHeadless returns true.
180    *
181    * @since 1.3
182    */
183   public Window(Window owner, GraphicsConfiguration gc)
184   {
185     this ();
186
187     synchronized (getTreeLock())
188       {
189         if (owner == null)
190           throw new IllegalArgumentException ("owner must not be null");
191
192         parent = owner;
193         owner.ownedWindows.add(new WeakReference(this));
194       }
195
196     // FIXME: make this text visible in the window.
197     SecurityManager s = System.getSecurityManager();
198     if (s != null && ! s.checkTopLevelWindow(this))
199       warningString = System.getProperty("awt.appletWarning");
200
201     if (gc != null
202         && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN)
203       throw new IllegalArgumentException ("gc must be from a screen device");
204
205     if (gc == null)
206       graphicsConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
207                                           .getDefaultScreenDevice()
208                                           .getDefaultConfiguration();
209     else
210       graphicsConfig = gc;
211   }
212
213   /**
214    * Creates the native peer for this window.
215    */
216   public void addNotify()
217   {
218     if (peer == null)
219       peer = getToolkit().createWindow(this);
220     super.addNotify();
221   }
222
223   /**
224    * Relays out this window's child components at their preferred size.
225    *
226    * @specnote pack() doesn't appear to be called internally by show(), so
227    *             we duplicate some of the functionality.
228    */
229   public void pack()
230   {
231     if (parent != null && !parent.isDisplayable())
232       parent.addNotify();
233     if (peer == null)
234       addNotify();
235
236     setSize(getPreferredSize());
237
238     validate();
239   }
240
241   /**
242    * Shows on-screen this window and any of its owned windows for whom
243    * isVisible returns true.
244    * @specnote: Deprecated starting in 1.5.
245    */
246   @Deprecated
247   public void show()
248   {
249     synchronized (getTreeLock())
250       {
251         if (peer == null)
252           addNotify();
253
254         validate();
255         if (visible)
256           toFront();
257         else
258           {
259             super.show();
260             // Show visible owned windows.
261             Iterator e = ownedWindows.iterator();
262             while (e.hasNext())
263               {
264                 Window w = (Window) (((Reference) e.next()).get());
265                 if (w != null)
266                   {
267                     if (w.isVisible())
268                       w.getPeer().setVisible(true);
269                   }
270                 else
271                   // Remove null weak reference from ownedWindows.
272                   // Unfortunately this can't be done in the Window's
273                   // finalize method because there is no way to guarantee
274                   // synchronous access to ownedWindows there.
275                   e.remove();
276               }
277           }
278         KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
279         manager.setGlobalFocusedWindow(this);
280
281         if (! shown)
282           {
283             FocusTraversalPolicy policy = getFocusTraversalPolicy();
284             Component initialFocusOwner = null;
285
286             if (policy != null)
287               initialFocusOwner = policy.getInitialComponent(this);
288
289             if (initialFocusOwner != null)
290               initialFocusOwner.requestFocusInWindow();
291
292             // Post WINDOW_OPENED from here.
293             if (windowListener != null
294                 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
295               {
296                 WindowEvent ev = new WindowEvent(this,
297                                                  WindowEvent.WINDOW_OPENED);
298                 Toolkit tk = Toolkit.getDefaultToolkit();
299                 tk.getSystemEventQueue().postEvent(ev);
300               }
301             shown = true;
302           }
303       }
304   }
305
306   /**
307    * @specnote: Deprecated starting in 1.5.
308    */
309   @Deprecated
310   public void hide()
311   {
312     // Hide visible owned windows.
313     synchronized (getTreeLock ())
314       {
315         Iterator e = ownedWindows.iterator();
316         while(e.hasNext())
317           {
318             Window w = (Window)(((Reference) e.next()).get());
319             if (w != null)
320               {
321                 if (w.isVisible() && w.getPeer() != null)
322                   w.getPeer().setVisible(false);
323               }
324             else
325               e.remove();
326           }
327       }
328     super.hide();
329   }
330
331   /**
332    * Destroys any resources associated with this window.  This includes
333    * all components in the window and all owned top-level windows.
334    */
335   public void dispose()
336   {
337     hide();
338
339     synchronized (getTreeLock ())
340       {
341         Iterator e = ownedWindows.iterator();
342         while(e.hasNext())
343           {
344             Window w = (Window)(((Reference) e.next()).get());
345             if (w != null)
346               w.dispose();
347             else
348               // Remove null weak reference from ownedWindows.
349               e.remove();
350           }
351
352         for (int i = 0; i < ncomponents; ++i)
353           component[i].removeNotify();
354         this.removeNotify();
355
356         // Post WINDOW_CLOSED from here.
357         if (windowListener != null
358             || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
359           {
360             WindowEvent ev = new WindowEvent(this,
361                                              WindowEvent.WINDOW_CLOSED);
362             Toolkit tk = Toolkit.getDefaultToolkit();
363             tk.getSystemEventQueue().postEvent(ev);
364           }
365       }
366   }
367
368   /**
369    * Sends this window to the back so that all other windows display in
370    * front of it.
371    *
372    * If the window is set to be always-on-top, this will remove its
373    * always-on-top status.
374    */
375   public void toBack()
376   {
377     if (peer != null)
378       {
379         if( alwaysOnTop )
380           setAlwaysOnTop( false );
381         ( (WindowPeer) peer ).toBack();
382       }
383   }
384
385   /**
386    * Brings this window to the front so that it displays in front of
387    * any other windows.
388    */
389   public void toFront()
390   {
391     if (peer != null)
392       ( (WindowPeer) peer ).toFront();
393   }
394
395   /**
396    * Returns the toolkit used to create this window.
397    *
398    * @return The toolkit used to create this window.
399    *
400    * @specnote Unlike Component.getToolkit, this implementation always 
401    *           returns the value of Toolkit.getDefaultToolkit().
402    */
403   public Toolkit getToolkit()
404   {
405     return Toolkit.getDefaultToolkit();    
406   }
407
408   /**
409    * Returns the warning string that will be displayed if this window is
410    * popped up by an unsecure applet or application.
411    *
412    * @return The unsecure window warning message.
413    */
414   public final String getWarningString()
415   {
416     return warningString;
417   }
418
419   /**
420    * Returns the locale that this window is configured for.
421    *
422    * @return The locale this window is configured for.
423    */
424   public Locale getLocale()
425   {
426     return locale == null ? Locale.getDefault() : locale;
427   }
428
429   /*
430   /** @since 1.2
431   public InputContext getInputContext()
432   {
433     // FIXME
434   }
435   */
436
437   /**
438    * Sets the cursor for this window to the specifiec cursor.
439    *
440    * @param cursor The new cursor for this window.
441    */
442   public void setCursor(Cursor cursor)
443   {
444     super.setCursor(cursor);
445   }
446
447   public Window getOwner()
448   {
449     return (Window) parent;
450   }
451
452   /** @since 1.2 */
453   public Window[] getOwnedWindows()
454   {
455     Window [] trimmedList;
456     synchronized (getTreeLock ())
457       {
458         // Windows with non-null weak references in ownedWindows.
459         Window [] validList = new Window [ownedWindows.size()];
460
461         Iterator e = ownedWindows.iterator();
462         int numValid = 0;
463         while (e.hasNext())
464           {
465             Window w = (Window)(((Reference) e.next()).get());
466             if (w != null)
467               validList[numValid++] = w;
468             else
469               // Remove null weak reference from ownedWindows.
470               e.remove();
471           }
472
473         if (numValid != validList.length)
474           {
475             trimmedList = new Window [numValid];
476             System.arraycopy (validList, 0, trimmedList, 0, numValid);
477           }
478         else
479           trimmedList = validList;
480       }
481     return trimmedList;
482   }
483
484   /**
485    * Adds the specified listener to the list of <code>WindowListeners</code>
486    * that will receive events for this window.
487    *
488    * @param listener The <code>WindowListener</code> to add.
489    */
490   public synchronized void addWindowListener(WindowListener listener)
491   {
492     if (listener != null)
493       {
494         newEventsOnly = true;
495         windowListener = AWTEventMulticaster.add(windowListener, listener);
496       }
497   }
498
499   /**
500    * Removes the specified listener from the list of
501    * <code>WindowListeners</code> that will receive events for this window.
502    *
503    * @param listener The <code>WindowListener</code> to remove.
504    */
505   public synchronized void removeWindowListener(WindowListener listener)
506   {
507     windowListener = AWTEventMulticaster.remove(windowListener, listener);
508   }
509
510   /**
511    * Returns an array of all the window listeners registered on this window.
512    *
513    * @since 1.4
514    */
515   public synchronized WindowListener[] getWindowListeners()
516   {
517     return (WindowListener[])
518       AWTEventMulticaster.getListeners(windowListener,
519                                        WindowListener.class);
520   }
521
522   /**
523    * Returns an array of all the window focus listeners registered on this
524    * window.
525    *
526    * @since 1.4
527    */
528   public synchronized WindowFocusListener[] getWindowFocusListeners()
529   {
530     return (WindowFocusListener[])
531       AWTEventMulticaster.getListeners(windowFocusListener,
532                                        WindowFocusListener.class);
533   }
534   
535   /**
536    * Returns an array of all the window state listeners registered on this
537    * window.
538    *
539    * @since 1.4
540    */
541   public synchronized WindowStateListener[] getWindowStateListeners()
542   {
543     return (WindowStateListener[])
544       AWTEventMulticaster.getListeners(windowStateListener,
545                                        WindowStateListener.class);
546   }
547
548   /**
549    * Adds the specified listener to this window.
550    */
551   public void addWindowFocusListener (WindowFocusListener wfl)
552   {
553     if (wfl != null)
554       {
555         newEventsOnly = true;
556         windowFocusListener = AWTEventMulticaster.add (windowFocusListener,
557                                                        wfl);
558       }
559   }
560   
561   /**
562    * Adds the specified listener to this window.
563    *
564    * @since 1.4
565    */
566   public void addWindowStateListener (WindowStateListener wsl)
567   {
568     if (wsl != null)
569       {
570         newEventsOnly = true;
571         windowStateListener = AWTEventMulticaster.add (windowStateListener,
572                                                        wsl);  
573       }
574   }
575   
576   /**
577    * Removes the specified listener from this window.
578    */
579   public void removeWindowFocusListener (WindowFocusListener wfl)
580   {
581     windowFocusListener = AWTEventMulticaster.remove (windowFocusListener, wfl);
582   }
583   
584   /**
585    * Removes the specified listener from this window.
586    *
587    * @since 1.4
588    */
589   public void removeWindowStateListener (WindowStateListener wsl)
590   {
591     windowStateListener = AWTEventMulticaster.remove (windowStateListener, wsl);
592   }
593
594   /**
595    * Returns an array of all the objects currently registered as FooListeners
596    * upon this Window. FooListeners are registered using the addFooListener
597    * method.
598    *
599    * @exception ClassCastException If listenerType doesn't specify a class or
600    * interface that implements java.util.EventListener.
601    *
602    * @since 1.3
603    */
604   public <T extends EventListener> T[] getListeners(Class<T> listenerType)
605   {
606     if (listenerType == WindowListener.class)
607       return (T[]) getWindowListeners();
608     return super.getListeners(listenerType);
609   }
610
611   void dispatchEventImpl(AWTEvent e)
612   {
613     if (e.getID() == ComponentEvent.COMPONENT_RESIZED)
614       {
615         invalidate();
616         validate();
617       }
618     super.dispatchEventImpl(e);
619   }
620
621   /**
622    * Processes the specified event for this window.  If the event is an
623    * instance of <code>WindowEvent</code>, then
624    * <code>processWindowEvent()</code> is called to process the event,
625    * otherwise the superclass version of this method is invoked.
626    *
627    * @param evt The event to process.
628    */
629   protected void processEvent(AWTEvent evt)
630   {
631     if (evt instanceof WindowEvent)
632       {
633         WindowEvent we = (WindowEvent) evt;
634         switch (evt.getID())
635           {
636           case WindowEvent.WINDOW_OPENED:
637           case WindowEvent.WINDOW_CLOSED:
638           case WindowEvent.WINDOW_CLOSING:
639           case WindowEvent.WINDOW_ICONIFIED:
640           case WindowEvent.WINDOW_DEICONIFIED:
641           case WindowEvent.WINDOW_ACTIVATED:
642           case WindowEvent.WINDOW_DEACTIVATED:
643             processWindowEvent(we);
644             break;
645           case WindowEvent.WINDOW_GAINED_FOCUS:
646           case WindowEvent.WINDOW_LOST_FOCUS:
647             processWindowFocusEvent(we);
648             break;
649           case WindowEvent.WINDOW_STATE_CHANGED:
650             processWindowStateEvent(we);
651             break;
652           }
653       }
654     else
655       super.processEvent(evt);
656   }
657
658   /**
659    * Dispatches this event to any listeners that are listening for
660    * <code>WindowEvents</code> on this window.  This method only gets
661    * invoked if it is enabled via <code>enableEvents()</code> or if
662    * a listener has been added.
663    *
664    * @param evt The event to process.
665    */
666   protected void processWindowEvent(WindowEvent evt)
667   {
668     if (windowListener != null)
669       {
670         switch (evt.getID())
671           {
672           case WindowEvent.WINDOW_ACTIVATED:
673             windowListener.windowActivated(evt);
674             break;
675           case WindowEvent.WINDOW_CLOSED:
676             windowListener.windowClosed(evt);
677             break;
678           case WindowEvent.WINDOW_CLOSING:
679             windowListener.windowClosing(evt);
680             break;
681           case WindowEvent.WINDOW_DEACTIVATED:
682             windowListener.windowDeactivated(evt);
683             break;
684           case WindowEvent.WINDOW_DEICONIFIED:
685             windowListener.windowDeiconified(evt);
686             break;
687           case WindowEvent.WINDOW_ICONIFIED:
688             windowListener.windowIconified(evt);
689             break;
690           case WindowEvent.WINDOW_OPENED:
691             windowListener.windowOpened(evt);
692             break;
693           }
694       }
695   }
696
697   /**
698    * Identifies if this window is active.  The active window is a Frame or
699    * Dialog that has focus or owns the active window.
700    *  
701    * @return true if active, else false.
702    * @since 1.4
703    */
704   public boolean isActive()
705   {
706     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
707     return manager.getActiveWindow() == this;
708   }
709
710   /**
711    * Identifies if this window is focused.  A window is focused if it is the
712    * focus owner or it contains the focus owner.
713    * 
714    * @return true if focused, else false.
715    * @since 1.4
716    */
717   public boolean isFocused()
718   {
719     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
720     return manager.getFocusedWindow() == this;
721   }
722   
723   /**
724    * Returns the child window that has focus if this window is active.
725    * This method returns <code>null</code> if this window is not active
726    * or no children have focus.
727    *
728    * @return The component that has focus, or <code>null</code> if no
729    * component has focus.
730    */
731   public Component getFocusOwner ()
732   {
733     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
734
735     Window activeWindow = manager.getActiveWindow ();
736
737     // The currently-focused Component belongs to the active Window.
738     if (activeWindow == this)
739       return manager.getFocusOwner ();
740     else
741       return null;
742   }
743
744   /**
745    * Returns the child component of this window that would receive
746    * focus if this window were to become focused.  If the window
747    * already has the top-level focus, then this method returns the
748    * same component as getFocusOwner.  If no child component has
749    * requested focus within the window, then the initial focus owner
750    * is returned.  If this is a non-focusable window, this method
751    * returns null.
752    *
753    * @return the child component of this window that most recently had
754    * the focus, or <code>null</code>
755    * @since 1.4
756    */
757   public Component getMostRecentFocusOwner ()
758   {
759     return windowFocusOwner;
760   }
761
762   /**
763    * Set the focus owner for this window.  This method is used to
764    * remember which component was focused when this window lost
765    * top-level focus, so that when it regains top-level focus the same
766    * child component can be refocused.
767    *
768    * @param windowFocusOwner the component in this window that owns
769    * the focus.
770    */
771   void setFocusOwner (Component windowFocusOwner)
772   {
773     this.windowFocusOwner = windowFocusOwner;
774   }
775
776   /**
777    * Post a Java 1.0 event to the event queue.
778    *
779    * @param e The event to post.
780    *
781    * @deprecated
782    */
783   public boolean postEvent(Event e)
784   {
785     return handleEvent (e);
786   }
787
788   /**
789    * Tests whether or not this window is visible on the screen.
790    *
791    * In contrast to the normal behaviour of Container, which is that
792    * a container is showing if its parent is visible and showing, a Window
793    * is even showing, if its parent (i.e. an invisible Frame) is not showing.
794    *
795    * @return <code>true</code> if this window is visible, <code>false</code>
796    * otherwise.
797    */
798   public boolean isShowing()
799   {
800     return isVisible();
801   }
802
803   public void setLocationRelativeTo(Component c)
804   {
805     int x = 0;
806     int y = 0;
807     
808     if (c == null || !c.isShowing())
809       {
810         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
811         Point center = ge.getCenterPoint();
812         x = center.x - (width / 2);
813         y = center.y - (height / 2);
814       }
815     else
816       {
817         int cWidth = c.getWidth();
818         int cHeight = c.getHeight();
819         Dimension screenSize = getToolkit().getScreenSize();
820
821         x = c.getLocationOnScreen().x;
822         y = c.getLocationOnScreen().y;
823         
824         // If bottom of component is cut off, window placed
825         // on the left or the right side of component
826         if ((y + cHeight) > screenSize.height)
827           {
828             // If the right side of the component is closer to the center
829             if ((screenSize.width / 2 - x) <= 0)
830               {
831                 if ((x - width) >= 0)
832                   x -= width;
833                 else
834                   x = 0;
835               }
836             else
837               {
838                 if ((x + cWidth + width) <= screenSize.width)
839                   x += cWidth;
840                 else
841                   x = screenSize.width - width;
842               }
843
844             y = screenSize.height - height;
845           }
846         else if (cWidth > width || cHeight > height)
847           {
848             // If right side of component is cut off
849             if ((x + width) > screenSize.width)
850               x = screenSize.width - width;
851             // If left side of component is cut off
852             else if (x < 0)
853               x = 0;
854             else
855               x += (cWidth - width) / 2;
856             
857             y += (cHeight - height) / 2;
858           }
859         else
860           {
861             // If right side of component is cut off
862             if ((x + width) > screenSize.width)
863               x = screenSize.width - width;
864             // If left side of component is cut off
865             else if (x < 0 || (x - (width - cWidth) / 2) < 0)
866               x = 0;
867             else
868               x -= (width - cWidth) / 2;
869
870             if ((y - (height - cHeight) / 2) > 0)
871               y -= (height - cHeight) / 2;
872             else
873               y = 0;
874           }
875       }
876
877     setLocation(x, y);
878   }
879
880   /**
881    * A BltBufferStrategy for windows.
882    */
883   private class WindowBltBufferStrategy extends BltBufferStrategy
884   {
885     /**
886      * Creates a block transfer strategy for this window.
887      *
888      * @param numBuffers the number of buffers in this strategy
889      * @param accelerated true if the buffer should be accelerated,
890      * false otherwise
891      */
892     WindowBltBufferStrategy(int numBuffers, boolean accelerated)
893     {
894       super(numBuffers,
895             new BufferCapabilities(new ImageCapabilities(accelerated),
896                                    new ImageCapabilities(accelerated),
897                                    BufferCapabilities.FlipContents.COPIED));
898     }
899   }
900
901   /**
902    * A FlipBufferStrategy for windows.
903    */
904   private class WindowFlipBufferStrategy extends FlipBufferStrategy
905   {
906     /**
907      * Creates a flip buffer strategy for this window.
908      *
909      * @param numBuffers the number of buffers in this strategy
910      *
911      * @throws AWTException if the requested number of buffers is not
912      * supported
913      */
914     WindowFlipBufferStrategy(int numBuffers)
915       throws AWTException
916     {
917       super(numBuffers,
918             new BufferCapabilities(new ImageCapabilities(true),
919                                    new ImageCapabilities(true),
920                                    BufferCapabilities.FlipContents.COPIED));
921     }
922   }
923
924   /**
925    * Creates a buffering strategy that manages how this window is
926    * repainted.  This method attempts to create the optimum strategy
927    * based on the desired number of buffers.  Hardware or software
928    * acceleration may be used.
929    *
930    * createBufferStrategy attempts different levels of optimization,
931    * but guarantees that some strategy with the requested number of
932    * buffers will be created even if it is not optimal.  First it
933    * attempts to create a page flipping strategy, then an accelerated
934    * blitting strategy, then an unaccelerated blitting strategy.
935    *
936    * Calling this method causes any existing buffer strategy to be
937    * destroyed.
938    *
939    * @param numBuffers the number of buffers in this strategy
940    *
941    * @throws IllegalArgumentException if requested number of buffers
942    * is less than one
943    * @throws IllegalStateException if this window is not displayable
944    *
945    * @since 1.4
946    */
947   public void createBufferStrategy(int numBuffers)
948   {
949     if (numBuffers < 1)
950       throw new IllegalArgumentException("Window.createBufferStrategy: number"
951                                          + " of buffers is less than one");
952
953     if (!isDisplayable())
954       throw new IllegalStateException("Window.createBufferStrategy: window is"
955                                       + " not displayable");
956
957     BufferStrategy newStrategy = null;
958
959     // try a flipping strategy
960     try
961       {
962         newStrategy = new WindowFlipBufferStrategy(numBuffers);
963       }
964     catch (AWTException e)
965       {
966       }
967
968     // fall back to an accelerated blitting strategy
969     if (newStrategy == null)
970       newStrategy = new WindowBltBufferStrategy(numBuffers, true);
971
972     bufferStrategy = newStrategy;
973   }
974
975   /**
976    * Creates a buffering strategy that manages how this window is
977    * repainted.  This method attempts to create a strategy based on
978    * the specified capabilities and throws an exception if the
979    * requested strategy is not supported.
980    *
981    * Calling this method causes any existing buffer strategy to be
982    * destroyed.
983    *
984    * @param numBuffers the number of buffers in this strategy
985    * @param caps the requested buffering capabilities
986    *
987    * @throws AWTException if the requested capabilities are not
988    * supported
989    * @throws IllegalArgumentException if requested number of buffers
990    * is less than one or if caps is null
991    *
992    * @since 1.4
993    */
994   public void createBufferStrategy(int numBuffers, BufferCapabilities caps)
995     throws AWTException
996   {
997     if (numBuffers < 1)
998       throw new IllegalArgumentException("Window.createBufferStrategy: number"
999                                          + " of buffers is less than one");
1000
1001     if (caps == null)
1002       throw new IllegalArgumentException("Window.createBufferStrategy:"
1003                                          + " capabilities object is null");
1004
1005     // a flipping strategy was requested
1006     if (caps.isPageFlipping())
1007       bufferStrategy = new WindowFlipBufferStrategy(numBuffers);
1008     else
1009       bufferStrategy = new WindowBltBufferStrategy(numBuffers, true);
1010   }
1011
1012   /**
1013    * Returns the buffer strategy used by the window.
1014    *
1015    * @return the buffer strategy.
1016    * @since 1.4
1017    */
1018   public BufferStrategy getBufferStrategy()
1019   {
1020     return bufferStrategy;
1021   }
1022
1023   /**
1024    * @since 1.2
1025    *
1026    * @deprecated replaced by Component.applyComponentOrientation.
1027    */
1028   public void applyResourceBundle(ResourceBundle rb)
1029   {
1030     applyComponentOrientation(ComponentOrientation.getOrientation(rb));
1031   }
1032
1033   /**
1034    * @since 1.2
1035    *
1036    * @deprecated
1037    */
1038   public void applyResourceBundle(String rbName)
1039   {
1040     ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(),
1041       ClassLoader.getSystemClassLoader());
1042     if (rb != null)
1043       applyResourceBundle(rb);    
1044   }
1045
1046   /**
1047    * Gets the AccessibleContext associated with this <code>Window</code>.
1048    * The context is created, if necessary.
1049    *
1050    * @return the associated context
1051    */
1052   public AccessibleContext getAccessibleContext()
1053   {
1054     /* Create the context if this is the first request */
1055     if (accessibleContext == null)
1056       accessibleContext = new AccessibleAWTWindow();
1057     return accessibleContext;
1058   }
1059
1060   /** 
1061    * Get graphics configuration.  The implementation for Window will
1062    * not ask any parent containers, since Window is a toplevel
1063    * window and not actually embedded in the parent component.
1064    */
1065   public GraphicsConfiguration getGraphicsConfiguration()
1066   {
1067     GraphicsConfiguration conf = graphicsConfig;
1068     if (conf == null)
1069       {
1070         conf = GraphicsEnvironment.getLocalGraphicsEnvironment()
1071         .getDefaultScreenDevice().getDefaultConfiguration();
1072         graphicsConfig = conf;
1073       }
1074     return conf;
1075   }
1076
1077   protected void processWindowFocusEvent(WindowEvent event)
1078   {
1079     if (windowFocusListener != null)
1080       {
1081         switch (event.getID ())
1082           {
1083           case WindowEvent.WINDOW_GAINED_FOCUS:
1084             windowFocusListener.windowGainedFocus (event);
1085             break;
1086             
1087           case WindowEvent.WINDOW_LOST_FOCUS:
1088             windowFocusListener.windowLostFocus (event);
1089             break;
1090             
1091           default:
1092             break;
1093           }
1094       }
1095   }
1096   
1097   /**
1098    * @since 1.4
1099    */
1100   protected void processWindowStateEvent(WindowEvent event)
1101   {
1102     if (windowStateListener != null
1103         && event.getID () == WindowEvent.WINDOW_STATE_CHANGED)
1104       windowStateListener.windowStateChanged (event);
1105   }
1106
1107   /**
1108    * Returns whether this <code>Window</code> can get the focus or not.
1109    *
1110    * @since 1.4
1111    */
1112   public final boolean isFocusableWindow ()
1113   {
1114     if (getFocusableWindowState () == false)
1115       return false;
1116
1117     if (this instanceof Dialog
1118         || this instanceof Frame)
1119       return true;
1120
1121     // FIXME: Implement more possible cases for returning true.
1122
1123     return false;
1124   }
1125   
1126   /**
1127    * Returns the value of the focusableWindowState property.
1128    * 
1129    * @since 1.4
1130    */
1131   public boolean getFocusableWindowState ()
1132   {
1133     return focusableWindowState;
1134   }
1135
1136   /**
1137    * Sets the value of the focusableWindowState property.
1138    * 
1139    * @since 1.4
1140    */
1141   public void setFocusableWindowState (boolean focusableWindowState)
1142   {
1143     this.focusableWindowState = focusableWindowState;
1144   }
1145   
1146   /**
1147    * Check whether this Container is a focus cycle root.
1148    * Returns always <code>true</code> as Windows are the 
1149    * root of the focus cycle.
1150    *
1151    * @return Always <code>true</code>.
1152    *
1153    * @since 1.4
1154    */
1155   public final boolean isFocusCycleRoot()
1156   {
1157     return true;
1158   }
1159
1160   /**
1161    * Set whether or not this Container is the root of a focus
1162    * traversal cycle. Windows are the root of the focus cycle
1163    * and therefore this method does nothing.
1164    * 
1165    * @param focusCycleRoot ignored.
1166    *
1167    * @since 1.4
1168    */
1169   public final void setFocusCycleRoot(boolean focusCycleRoot)
1170   {
1171     // calls to the method are ignored
1172   }
1173
1174   /**
1175    * Returns the root container that owns the focus cycle where this
1176    * component resides. Windows have no ancestors and this method
1177    * returns always <code>null</code>.
1178    *
1179    * @return Always <code>null</code>.
1180    * @since 1.4
1181    */
1182   public final Container getFocusCycleRootAncestor()
1183   {
1184     return null;
1185   }
1186
1187   /**
1188    * Returns whether the Windows is an always-on-top window,
1189    * meaning whether the window can be obscured by other windows or not.
1190    *
1191    * @return <code>true</code> if the windows is always-on-top,
1192    * <code>false</code> otherwise.
1193    * @since 1.5
1194    */
1195   public final boolean isAlwaysOnTop()
1196   {
1197     return alwaysOnTop;
1198   }
1199
1200   /**
1201    * Sets the always-on-top state of this window (if supported).
1202    *
1203    * Setting a window to always-on-top means it will not be obscured
1204    * by any other windows (with the exception of other always-on-top 
1205    * windows). Not all platforms may support this.
1206    *
1207    * If an window's always-on-top status is changed to false, the window
1208    * will remain at the front but not be anchored there.
1209    *
1210    * Calling toBack() on an always-on-top window will change its
1211    * always-on-top status to false.
1212    *
1213    * @since 1.5
1214    */
1215   public final void setAlwaysOnTop(boolean alwaysOnTop)
1216   {
1217     SecurityManager sm = System.getSecurityManager();
1218     if (sm != null)
1219       sm.checkPermission( new AWTPermission("setWindowAlwaysOnTop") );
1220
1221     if( this.alwaysOnTop == alwaysOnTop )
1222       return;
1223     
1224     if( alwaysOnTop )
1225       toFront();
1226
1227     firePropertyChange("alwaysOnTop", this.alwaysOnTop, alwaysOnTop );
1228     this.alwaysOnTop = alwaysOnTop;
1229
1230     if (peer != null) 
1231       ( (WindowPeer) peer).updateAlwaysOnTop();
1232     else
1233       System.out.println("Null peer?!");
1234   }
1235
1236   /**
1237    * Generate a unique name for this window.
1238    *
1239    * @return A unique name for this window.
1240    */
1241   String generateName()
1242   {
1243     return "win" + getUniqueLong();
1244   }
1245
1246   /**
1247    * Overridden to handle WindowEvents.
1248    *
1249    * @return <code>true</code> when the specified event type is enabled,
1250    *         <code>false</code> otherwise
1251    */
1252   boolean eventTypeEnabled(int type)
1253   {
1254     boolean enabled = false;
1255     switch (type)
1256       {
1257         case WindowEvent.WINDOW_OPENED:
1258         case WindowEvent.WINDOW_CLOSED:
1259         case WindowEvent.WINDOW_CLOSING:
1260         case WindowEvent.WINDOW_ICONIFIED:
1261         case WindowEvent.WINDOW_DEICONIFIED:
1262         case WindowEvent.WINDOW_ACTIVATED:
1263         case WindowEvent.WINDOW_DEACTIVATED:
1264           enabled = ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
1265                     || windowListener != null;
1266           break;
1267         case WindowEvent.WINDOW_GAINED_FOCUS:
1268         case WindowEvent.WINDOW_LOST_FOCUS:
1269           enabled = ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0)
1270                     || windowFocusListener != null;
1271           break;
1272         case WindowEvent.WINDOW_STATE_CHANGED:
1273           enabled = ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0)
1274                     || windowStateListener != null;
1275           break;
1276         default:
1277           enabled = super.eventTypeEnabled(type);
1278       }
1279     return enabled;
1280   }
1281
1282   private static synchronized long getUniqueLong()
1283   {
1284     return next_window_number++;
1285   }
1286 }