OSDN Git Service

2003-06-27 Michael Koch <konqueror@gmx.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / Window.java
1 /* Window.java --
2    Copyright (C) 1999, 2000, 2002, 2003 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.WindowEvent;
42 import java.awt.event.WindowFocusListener;
43 import java.awt.event.WindowListener;
44 import java.awt.event.WindowStateListener;
45 import java.awt.peer.WindowPeer;
46 import java.util.EventListener;
47 import java.util.Locale;
48 import java.util.ResourceBundle;
49 import javax.accessibility.Accessible;
50 import javax.accessibility.AccessibleContext;
51
52 /**
53  * This class represents a top-level window with no decorations.
54  *
55  * @author Aaron M. Renn <arenn@urbanophile.com>
56  * @author Warren Levy  <warrenl@cygnus.com>
57  */
58 public class Window extends Container implements Accessible
59 {
60   private static final long serialVersionUID = 4497834738069338734L;
61
62   // Serialized fields, from Sun's serialization spec.
63   private String warningString = null;
64   private int windowSerializedDataVersion = 0; // FIXME
65   /** @since 1.2 */
66   // private FocusManager focusMgr;  // FIXME: what is this?  
67   /** @since 1.2 */
68   private int state = 0;
69   /** @since 1.4 */
70   private boolean focusableWindowState = true;
71
72   private transient WindowListener windowListener;
73   private transient WindowFocusListener windowFocusListener;
74   private transient WindowStateListener windowStateListener;
75   private transient GraphicsConfiguration graphicsConfiguration;
76   private transient AccessibleContext accessibleContext;
77
78   /** 
79    * This (package access) constructor is used by subclasses that want
80    * to build windows that do not have parents.  Eg. toplevel
81    * application frames.  Subclasses cannot call super(null), since
82    * null is an illegal argument.
83    */
84   Window()
85   {
86     setVisible(false);
87     setLayout(new BorderLayout());
88   }
89
90   Window(GraphicsConfiguration gc)
91   {
92     this();
93     graphicsConfiguration = gc;
94   }
95
96   /**
97    * Initializes a new instance of <code>Window</code> with the specified
98    * parent.  The window will initially be invisible.
99    *
100    * @param parent The owning <code>Frame</code> of this window.
101    *
102    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
103    * is not from a screen device, or if owner is null; this exception is always
104    * thrown when GraphicsEnvironment.isHeadless returns true.
105    */
106   public Window(Frame owner)
107   {
108     this (owner, owner.getGraphicsConfiguration ());
109   }
110
111   /**
112    * Initializes a new instance of <code>Window</code> with the specified
113    * parent.  The window will initially be invisible.   
114    *
115    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
116    * is not from a screen device, or if owner is null; this exception is always
117    * thrown when GraphicsEnvironment.isHeadless returns true.
118    *
119    * @since 1.2
120    */
121   public Window(Window owner)
122   {
123     this (owner, owner.getGraphicsConfiguration ());
124   }
125   
126   /**
127    * Initializes a new instance of <code>Window</code> with the specified
128    * parent.  The window will initially be invisible.   
129    *
130    * @exception IllegalArgumentException If owner is null or if gc is not from a
131    * screen device; this exception is always thrown when
132    * GraphicsEnvironment.isHeadless returns true.
133    *
134    * @since 1.3
135    */
136   public Window(Window owner, GraphicsConfiguration gc)
137   {
138     this ();
139
140     if (owner == null)
141       throw new IllegalArgumentException ("owner must not be null");
142
143     this.parent = owner;
144     
145     // FIXME: add to owner's "owned window" list
146     //owner.owned.add(this); // this should be a weak reference
147     
148     /*  FIXME: Security check
149     SecurityManager.checkTopLevelWindow(...)
150     */
151
152     if (gc != null
153         && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN)
154       throw new IllegalArgumentException ("gc must be from a screen device");
155
156     // FIXME: until we implement this, it just causes AWT to crash.
157 //     if (gc == null)
158 //       graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment()
159 //         .getDefaultScreenDevice()
160 //         .getDefaultConfiguration();
161 //     else
162       graphicsConfiguration = gc;
163   }
164
165   GraphicsConfiguration getGraphicsConfigurationImpl()
166   {
167     if (graphicsConfiguration != null)
168         return graphicsConfiguration;
169
170     return super.getGraphicsConfigurationImpl();
171   }
172
173   /**
174    * Disposes of the input methods and context, and removes the WeakReference
175    * which formerly pointed to this Window from the parent's owned Window list.
176    *
177    * @exception Throwable The Exception raised by this method.
178    */
179   protected void finalize() throws Throwable
180   {
181     // FIXME: remove from owner's "owned window" list (Weak References)
182     super.finalize();
183   }
184
185   /**
186    * Creates the native peer for this window.
187    */
188   public void addNotify()
189   {
190     if (peer == null)
191       peer = getToolkit().createWindow(this);
192     super.addNotify();
193   }
194
195   /**
196    * Relays out this window's child components at their preferred size.
197    *
198    * @specnote pack() doesn't appear to be called internally by show(), so
199    *             we duplicate some of the functionality.
200    */
201   public void pack()
202   {
203     if (parent != null && !parent.isDisplayable())
204       parent.addNotify();
205     if (peer == null)
206       addNotify();
207
208     setSize(getPreferredSize());
209
210     validate();
211   }
212
213   /**
214    * Makes this window visible and brings it to the front.
215    */
216   public void show()
217   {
218     if (parent != null && !parent.isDisplayable())
219       parent.addNotify();
220     if (peer == null)
221       addNotify();
222
223     validate();
224     super.show();
225     toFront();
226   }
227
228   public void hide()
229   {
230     // FIXME: call hide() on any "owned" children here.
231     super.hide();
232   }
233
234   public boolean isDisplayable()
235   {
236     if (super.isDisplayable())
237       return true;
238     return peer != null;
239   }
240
241   /**
242    * Called to free any resource associated with this window.
243    */
244   public void dispose()
245   {
246     hide();
247
248     Window[] list = getOwnedWindows();
249     for (int i=0; i<list.length; i++)
250       list[i].dispose();
251
252     for (int i = 0; i < ncomponents; ++i)
253       component[i].removeNotify();
254     this.removeNotify();
255   }
256
257   /**
258    * Sends this window to the back so that all other windows display in
259    * front of it.
260    */
261   public void toBack()
262   {
263     if (peer != null)
264       {
265         WindowPeer wp = (WindowPeer) peer;
266         wp.toBack();
267       }
268   }
269
270   /**
271    * Brings this window to the front so that it displays in front of
272    * any other windows.
273    */
274   public void toFront()
275   {
276     if (peer != null)
277       {
278         WindowPeer wp = (WindowPeer) peer;
279         wp.toFront();
280       }
281   }
282
283   /**
284    * Returns the toolkit used to create this window.
285    *
286    * @return The toolkit used to create this window.
287    *
288    * @specnote Unlike Component.getToolkit, this implementation always 
289    *           returns the value of Toolkit.getDefaultToolkit().
290    */
291   public Toolkit getToolkit()
292   {
293     return Toolkit.getDefaultToolkit();    
294   }
295
296   /**
297    * Returns the warning string that will be displayed if this window is
298    * popped up by an unsecure applet or application.
299    *
300    * @return The unsecure window warning message.
301    */
302   public final String getWarningString()
303   {
304     boolean secure = true;
305     /* boolean secure = SecurityManager.checkTopLevelWindow(...) */
306
307     if (!secure)
308       {
309         if (warningString != null)
310           return warningString;
311         else
312           {
313             String warning = System.getProperty("awt.appletWarning");
314             return warning;
315           }
316       }
317     return null;
318   }
319
320   /**
321    * Returns the locale that this window is configured for.
322    *
323    * @return The locale this window is configured for.
324    */
325   public Locale getLocale()
326   {
327     return locale == null ? Locale.getDefault() : locale;
328   }
329
330   /*
331   /** @since 1.2
332   public InputContext getInputContext()
333   {
334     // FIXME
335   }
336   */
337
338   /**
339    * Sets the cursor for this window to the specifiec cursor.
340    *
341    * @param cursor The new cursor for this window.
342    */
343   public void setCursor(Cursor cursor)
344   {
345     super.setCursor(cursor);
346   }
347
348   public Window getOwner()
349   {
350     return (Window) parent;
351   }
352
353   /** @since 1.2 */
354   public Window[] getOwnedWindows()
355   {
356     // FIXME: return array containing all the windows this window currently 
357     // owns.
358     return new Window[0];
359   }
360
361   /**
362    * Adds the specified listener to the list of <code>WindowListeners</code>
363    * that will receive events for this window.
364    *
365    * @param listener The <code>WindowListener</code> to add.
366    */
367   public synchronized void addWindowListener(WindowListener listener)
368   {
369     windowListener = AWTEventMulticaster.add(windowListener, listener);
370   }
371
372   /**
373    * Removes the specified listener from the list of
374    * <code>WindowListeners</code> that will receive events for this window.
375    *
376    * @param listener The <code>WindowListener</code> to remove.
377    */
378   public synchronized void removeWindowListener(WindowListener listener)
379   {
380     windowListener = AWTEventMulticaster.remove(windowListener, listener);
381   }
382
383   /**
384    * Returns an array of all the window listeners registered on this window.
385    *
386    * @since 1.4
387    */
388   public synchronized WindowListener[] getWindowListeners()
389   {
390     return (WindowListener[])
391       AWTEventMulticaster.getListeners(windowListener,
392                                        WindowListener.class);
393   }
394
395   /**
396    * Returns an array of all the window focus listeners registered on this
397    * window.
398    *
399    * @since 1.4
400    */
401   public synchronized WindowFocusListener[] getWindowFocusListeners()
402   {
403     return (WindowFocusListener[])
404       AWTEventMulticaster.getListeners(windowFocusListener,
405                                        WindowFocusListener.class);
406   }
407   
408   /**
409    * Returns an array of all the window state listeners registered on this
410    * window.
411    *
412    * @since 1.4
413    */
414   public synchronized WindowStateListener[] getWindowStateListeners()
415   {
416     return (WindowStateListener[])
417       AWTEventMulticaster.getListeners(windowStateListener,
418                                        WindowStateListener.class);
419   }
420
421   /**
422    * Adds the specified listener to this window.
423    */
424   public void addWindowFocusListener (WindowFocusListener wfl)
425   {
426     AWTEventMulticaster.add (windowFocusListener, wfl);
427   }
428   
429   /**
430    * Adds the specified listener to this window.
431    *
432    * @since 1.4
433    */
434   public void addWindowStateListener (WindowStateListener wsl)
435   {
436     AWTEventMulticaster.add (windowStateListener, wsl);  
437   }
438   
439   /**
440    * Removes the specified listener from this window.
441    */
442   public void removeWindowFocusListener (WindowFocusListener wfl)
443   {
444     AWTEventMulticaster.remove (windowFocusListener, wfl);
445   }
446   
447   /**
448    * Removes the specified listener from this window.
449    *
450    * @since 1.4
451    */
452   public void removeWindowStateListener (WindowStateListener wsl)
453   {
454     AWTEventMulticaster.remove (windowStateListener, wsl);
455   }
456
457   /**
458    * Returns an array of all the objects currently registered as FooListeners
459    * upon this Window. FooListeners are registered using the addFooListener
460    * method.
461    *
462    * @exception ClassCastException If listenerType doesn't specify a class or
463    * interface that implements java.util.EventListener.
464    *
465    * @since 1.3
466    */
467   public EventListener[] getListeners(Class listenerType)
468   {
469     if (listenerType == WindowListener.class)
470       return getWindowListeners();
471     return super.getListeners(listenerType);
472   }
473
474   void dispatchEventImpl(AWTEvent e)
475   {
476     // Make use of event id's in order to avoid multiple instanceof tests.
477     if (e.id <= WindowEvent.WINDOW_LAST 
478         && e.id >= WindowEvent.WINDOW_FIRST
479         && (windowListener != null 
480             || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0))
481       processEvent(e);
482     else
483       super.dispatchEventImpl(e);
484   }
485
486   /**
487    * Processes the specified event for this window.  If the event is an
488    * instance of <code>WindowEvent</code>, then
489    * <code>processWindowEvent()</code> is called to process the event,
490    * otherwise the superclass version of this method is invoked.
491    *
492    * @param event The event to process.
493    */
494   protected void processEvent(AWTEvent evt)
495   {
496     if (evt instanceof WindowEvent)
497       processWindowEvent((WindowEvent) evt);
498     else
499       super.processEvent(evt);
500   }
501
502   /**
503    * Dispatches this event to any listeners that are listening for
504    * <code>WindowEvents</code> on this window.  This method only gets
505    * invoked if it is enabled via <code>enableEvents()</code> or if
506    * a listener has been added.
507    *
508    * @param event The event to process.
509    */
510   protected void processWindowEvent(WindowEvent evt)
511   {
512     if (windowListener != null)
513       {
514         switch (evt.getID())
515           {
516           case WindowEvent.WINDOW_ACTIVATED:
517             windowListener.windowActivated(evt);
518             break;
519           case WindowEvent.WINDOW_CLOSED:
520             windowListener.windowClosed(evt);
521             break;
522           case WindowEvent.WINDOW_CLOSING:
523             windowListener.windowClosing(evt);
524             break;
525           case WindowEvent.WINDOW_DEACTIVATED:
526             windowListener.windowDeactivated(evt);
527             break;
528           case WindowEvent.WINDOW_DEICONIFIED:
529             windowListener.windowDeiconified(evt);
530             break;
531           case WindowEvent.WINDOW_ICONIFIED:
532             windowListener.windowIconified(evt);
533             break;
534           case WindowEvent.WINDOW_OPENED:
535             windowListener.windowOpened(evt);
536             break;
537           case WindowEvent.WINDOW_GAINED_FOCUS:
538           case WindowEvent.WINDOW_LOST_FOCUS:
539             processWindowFocusEvent (evt);
540             break;
541           case WindowEvent.WINDOW_STATE_CHANGED:
542             processWindowStateEvent (evt);
543             break;
544           }
545       }
546   }
547
548   /**
549    * Returns the child window that has focus if this window is active.
550    * This method returns <code>null</code> if this window is not active
551    * or no children have focus.
552    *
553    * @return The component that has focus, or <code>null</code> if no
554    * component has focus.
555    */
556   public Component getFocusOwner()
557   {
558     // FIXME
559     return null;
560   }
561
562   /**
563    * Post a Java 1.0 event to the event queue.
564    *
565    * @param event The event to post.
566    *
567    * @deprecated
568    */
569   public boolean postEvent(Event e)
570   {
571     // FIXME
572     return false;
573   }
574
575   /**
576    * Tests whether or not this window is visible on the screen.
577    *
578    * @return <code>true</code> if this window is visible, <code>false</code>
579    * otherwise.
580    */
581   public boolean isShowing()
582   {
583     return super.isShowing();
584   }
585
586   /**
587    * @since 1.2
588    *
589    * @deprecated
590    */
591   public void applyResourceBundle(ResourceBundle rb)
592   {
593     throw new Error ("Not implemented");
594   }
595
596   /**
597    * @since 1.2
598    *
599    * @deprecated
600    */
601   public void applyResourceBundle(String rbName)
602   {
603     ResourceBundle rb = ResourceBundle.getBundle(rbName);
604     if (rb != null)
605       applyResourceBundle(rb);    
606   }
607
608   public AccessibleContext getAccessibleContext()
609   {
610     // FIXME
611     //return null;
612     throw new Error ("Not implemented");
613   }
614
615   /** 
616    * Get graphics configuration.  The implementation for Window will
617    * not ask any parent containers, since Window is a toplevel
618    * window and not actually embedded in the parent component.
619    */
620   public GraphicsConfiguration getGraphicsConfiguration()
621   {
622     if (graphicsConfiguration != null) return graphicsConfiguration;
623     if (peer != null) return peer.getGraphicsConfiguration();
624     return null;
625   }
626
627   protected void processWindowFocusEvent(WindowEvent event)
628   {
629     if (windowFocusListener != null)
630       {
631         switch (event.getID ())
632           {
633           case WindowEvent.WINDOW_GAINED_FOCUS:
634             windowFocusListener.windowGainedFocus (event);
635             break;
636             
637           case WindowEvent.WINDOW_LOST_FOCUS:
638             windowFocusListener.windowLostFocus (event);
639             break;
640             
641           default:
642             break;
643           }
644       }
645   }
646   
647   /**
648    * @since 1.4
649    */
650   protected void processWindowStateEvent(WindowEvent event)
651   {
652     if (windowStateListener != null
653         && event.getID () == WindowEvent.WINDOW_STATE_CHANGED)
654       windowStateListener.windowStateChanged (event);
655   }
656
657   /**
658    * Returns whether this <code>Window</code> can get the focus or not.
659    *
660    * @since 1.4
661    */
662   public final boolean isFocusableWindow ()
663   {
664     if (getFocusableWindowState () == false)
665       return false;
666
667     if (this instanceof Dialog
668         || this instanceof Frame)
669       return true;
670
671     // FIXME: Implement more possible cases for returning true.
672
673     return false;
674   }
675   
676   /**
677    * Returns the value of the focusableWindowState property.
678    * 
679    * @since 1.4
680    */
681   public boolean getFocusableWindowState ()
682   {
683     return focusableWindowState;
684   }
685
686   /**
687    * Sets the value of the focusableWindowState property.
688    * 
689    * @since 1.4
690    */
691   public void setFocusableWindowState (boolean focusableWindowState)
692   {
693     this.focusableWindowState = focusableWindowState;
694   }
695 }