OSDN Git Service

Fix "make dvi"
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / Frame.java
1 /* Frame.java -- AWT toplevel window
2    Copyright (C) 1999, 2000, 2002, 2004, 2005  Free Software Foundation, Inc.
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.peer.FramePeer;
42 import java.lang.ref.WeakReference;
43 import java.util.ArrayList;
44 import java.util.Iterator;
45 import java.util.Vector;
46
47 import javax.accessibility.AccessibleContext;
48 import javax.accessibility.AccessibleRole;
49 import javax.accessibility.AccessibleState;
50 import javax.accessibility.AccessibleStateSet;
51
52 /**
53   * This class is a top-level window with a title bar and window
54   * decorations.
55   *
56   * @author Aaron M. Renn (arenn@urbanophile.com)
57   */
58 public class Frame extends Window implements MenuContainer
59 {
60 /**
61   * Constant for the default cursor.
62   * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead.
63   */
64 public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
65
66 /**
67   * Constant for a cross-hair cursor.
68   * @deprecated Use <code>Cursor.CROSSHAIR_CURSOR</code> instead.
69   */
70 public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
71
72 /**
73   * Constant for a cursor over a text field.
74   * @deprecated Use <code>Cursor.TEXT_CURSOR</code> instead.
75   */
76 public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
77
78 /**
79   * Constant for a cursor to display while waiting for an action to complete.
80   * @deprecated Use <code>Cursor.WAIT_CURSOR</code>.
81   */
82 public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
83
84 /**
85   * Cursor used over SW corner of window decorations.
86   * @deprecated Use <code>Cursor.SW_RESIZE_CURSOR</code> instead.
87   */
88 public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
89
90 /**
91   * Cursor used over SE corner of window decorations.
92   * @deprecated Use <code>Cursor.SE_RESIZE_CURSOR</code> instead.
93   */
94 public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
95
96 /**
97   * Cursor used over NW corner of window decorations.
98   * @deprecated Use <code>Cursor.NW_RESIZE_CURSOR</code> instead.
99   */
100 public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
101
102 /**
103   * Cursor used over NE corner of window decorations.
104   * @deprecated Use <code>Cursor.NE_RESIZE_CURSOR</code> instead.
105   */
106 public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
107
108 /**
109   * Cursor used over N edge of window decorations.
110   * @deprecated Use <code>Cursor.N_RESIZE_CURSOR</code> instead.
111   */
112 public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
113
114 /**
115   * Cursor used over S edge of window decorations.
116   * @deprecated Use <code>Cursor.S_RESIZE_CURSOR</code> instead.
117   */
118 public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
119
120 /**
121   * Cursor used over E edge of window decorations.
122   * @deprecated Use <code>Cursor.E_RESIZE_CURSOR</code> instead.
123   */
124 public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
125
126 /**
127   * Cursor used over W edge of window decorations.
128   * @deprecated Use <code>Cursor.W_RESIZE_CURSOR</code> instead.
129   */
130 public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
131
132 /**
133   * Constant for a hand cursor.
134   * @deprecated Use <code>Cursor.HAND_CURSOR</code> instead.
135   */
136 public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
137
138 /**
139   * Constant for a cursor used during window move operations.
140   * @deprecated Use <code>Cursor.MOVE_CURSOR</code> instead.
141   */
142 public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
143
144 public static final int ICONIFIED = 1;
145 public static final int MAXIMIZED_BOTH = 6;
146 public static final int MAXIMIZED_HORIZ = 2;
147 public static final int MAXIMIZED_VERT = 4;
148 public static final int NORMAL = 0;
149
150 // Serialization version constant
151 private static final long serialVersionUID = 2673458971256075116L;
152
153 /**
154   * @serial The version of the class data being serialized
155   * // FIXME: what is this value?
156   */
157 private int frameSerializedDataVersion;
158
159 /**
160   * @serial Image used as the icon when this frame is minimized.
161   */
162 private Image icon;
163
164 /**
165   * @serial Constant used by the JDK Motif peer set.  Not used in
166   * this implementation.
167   */
168 private boolean mbManagement;
169
170 /**
171   * @serial The menu bar for this frame.
172   */
173 //private MenuBar menuBar = new MenuBar();
174 private MenuBar menuBar;
175
176 /**
177   * @serial A list of other top-level windows owned by this window.
178   */
179 Vector ownedWindows = new Vector();
180
181 /**
182   * @serial Indicates whether or not this frame is resizable.
183   */
184 private boolean resizable = true;
185
186 /**
187   * @serial The state of this frame.
188   * // FIXME: What are the values here?
189   */
190 private int state;
191
192 /**
193   * @serial The title of the frame.
194   */
195 private String title = "";
196
197   /**
198    * Maximized bounds for this frame.
199    */
200   private Rectangle maximizedBounds;
201
202   /**
203    * This field indicates whether the frame is undecorated or not.
204    */
205   private boolean undecorated = false;
206
207   /*
208    * The number used to generate the name returned by getName.
209    */
210   private static transient long next_frame_number;
211
212 /**
213   * Initializes a new instance of <code>Frame</code> that is not visible
214   * and has no title.
215   */
216 public
217 Frame()
218 {
219   this("");
220   noteFrame(this);
221 }
222
223 /**
224   * Initializes a new instance of <code>Frame</code> that is not visible
225   * and has the specified title.
226   *
227   * @param title The title of this frame.
228   */
229 public
230 Frame(String title)
231 {
232   super();
233   this.title = title;
234   // Top-level frames are initially invisible.
235   visible = false;
236   noteFrame(this);
237 }
238
239 public
240 Frame(GraphicsConfiguration gc)
241 {
242   super(gc);
243   visible = false;
244   noteFrame(this);
245 }
246
247 public
248 Frame(String title, GraphicsConfiguration gc)
249 {
250   super(gc);
251   setTitle(title);
252   visible = false;
253   noteFrame(this);
254 }
255
256 /**
257   * Returns this frame's title string.
258   *
259   * @return This frame's title string.
260   */
261 public String
262 getTitle()
263 {
264   return(title);
265 }
266
267 /*
268  * Sets this frame's title to the specified value.
269  *
270  * @param title The new frame title.
271  */
272 public synchronized void
273 setTitle(String title)
274 {
275   this.title = title;
276   if (peer != null)
277     ((FramePeer) peer).setTitle(title);
278 }
279
280 /**
281   * Returns this frame's icon.
282   *
283   * @return This frame's icon, or <code>null</code> if this frame does not
284   * have an icon.
285   */
286 public Image
287 getIconImage()
288 {
289   return(icon);
290 }
291
292 /**
293   * Sets this frame's icon to the specified value.
294   *
295   * @icon The new icon for this frame.
296   */
297 public synchronized void
298 setIconImage(Image icon)
299 {
300   this.icon = icon;
301   if (peer != null)
302     ((FramePeer) peer).setIconImage(icon);
303 }
304
305 /**
306   * Returns this frame's menu bar.
307   *
308   * @return This frame's menu bar, or <code>null</code> if this frame
309   * does not have a menu bar.
310   */
311 public MenuBar
312 getMenuBar()
313 {
314   return(menuBar);
315 }
316
317 /**
318   * Sets this frame's menu bar.
319   *
320   * @param menuBar The new menu bar for this frame.
321   */
322 public synchronized void
323 setMenuBar(MenuBar menuBar)
324 {
325   if (peer != null)
326   {
327     if (this.menuBar != null)
328       this.menuBar.removeNotify();  
329     if (menuBar != null)
330       menuBar.addNotify();
331     invalidateTree ();
332     ((FramePeer) peer).setMenuBar(menuBar);
333   }
334   this.menuBar = menuBar;
335 }
336
337 /**
338   * Tests whether or not this frame is resizable.  This will be 
339   * <code>true</code> by default.
340   *
341   * @return <code>true</code> if this frame is resizable, <code>false</code>
342   * otherwise.
343   */
344 public boolean
345 isResizable()
346 {
347   return(resizable);
348 }
349
350 /**
351   * Sets the resizability of this frame to the specified value.
352   *
353   * @param resizable <code>true</code> to make the frame resizable,
354   * <code>false</code> to make it non-resizable.
355   */
356 public synchronized void
357 setResizable(boolean resizable)
358 {
359   this.resizable = resizable;
360   if (peer != null)
361     ((FramePeer) peer).setResizable(resizable);
362 }
363
364 /**
365   * Returns the cursor type of the cursor for this window.  This will
366   * be one of the constants in this class.
367   *
368   * @return The cursor type for this frame.
369   *
370   * @deprecated Use <code>Component.getCursor()</code> instead.
371   */
372 public int
373 getCursorType()
374 {
375   return(getCursor().getType());
376 }
377
378 /**
379   * Sets the cursor for this window to the specified type.  The specified
380   * type should be one of the constants in this class.
381   *
382   * @param type The cursor type.
383   *
384   * @deprecated Use <code>Component.setCursor(Cursor)</code> instead.
385   */
386 public void
387 setCursor(int type)
388 {
389   setCursor(new Cursor(type));
390 }
391
392 /**
393   * Removes the specified component from this frame's menu.
394   *
395   * @param menu The menu component to remove.
396   */
397 public void
398 remove(MenuComponent menu)
399 {
400   menuBar.remove(menu);
401 }
402
403 /**
404   * Notifies this frame that it should create its native peer.
405   */
406 private static void fireDummyEvent()
407 {
408   EventQueue.invokeLater(new Runnable()
409     {
410       public void run()
411       {
412         // Do nothing here.
413       }
414     });
415 }
416
417 public void
418 addNotify()
419 {
420   if (menuBar != null)
421     menuBar.addNotify();
422   if (peer == null)
423     peer = getToolkit ().createFrame (this);
424
425   // We now know there's a Frame (us) with a live peer, so we can start the
426   // fundamental queue and dispatch thread, by inserting a dummy event.
427   if (parent != null && parent.isDisplayable())
428     fireDummyEvent();
429   
430   super.addNotify();
431 }
432
433 public void removeNotify()
434 {
435   if (menuBar != null)
436     menuBar.removeNotify();
437   super.removeNotify();
438
439   // By now we've been disconnected from the peer, and the peer set to
440   // null.  This is formally the same as saying "we just became
441   // un-displayable", so we wake up the event queue with a dummy event to
442   // see if it's time to shut down.
443   fireDummyEvent();
444 }
445
446   /**
447    * Returns a debugging string describing this window.
448    *
449    * @return A debugging string describing this window.
450    */
451   protected String paramString ()
452   {
453     String title = getTitle ();
454
455     String resizable = "";
456     if (isResizable ())
457       resizable = ",resizable";
458
459     String state = "";
460     switch (getState ())
461       {
462       case NORMAL:
463         state = ",normal";
464         break;
465       case ICONIFIED:
466         state = ",iconified";
467         break;
468       case MAXIMIZED_BOTH:
469         state = ",maximized-both";
470         break;
471       case MAXIMIZED_HORIZ:
472         state = ",maximized-horiz";
473         break;
474       case MAXIMIZED_VERT:
475         state = ",maximized-vert";
476         break;
477       }
478
479     return super.paramString () + ",title=" + title + resizable + state;
480   }
481
482 private static ArrayList weakFrames = new ArrayList();
483
484 private static void noteFrame(Frame f)
485 {
486   weakFrames.add(new WeakReference(f));
487 }
488
489 public static Frame[] getFrames()
490 {
491   int n = 0;
492   synchronized (weakFrames)
493     {
494       Iterator i = weakFrames.iterator();
495       while (i.hasNext())
496         {
497           WeakReference wr = (WeakReference) i.next();
498           if (wr.get() != null)
499             ++n;
500         }
501       if (n == 0)
502         return new Frame[0];
503       else
504         {
505           Frame[] frames = new Frame[n];
506           n = 0;
507           i = weakFrames.iterator();
508           while (i.hasNext())
509             {
510               WeakReference wr = (WeakReference) i.next();
511               if (wr.get() != null)
512                 frames[n++] = (Frame) wr.get();
513             }
514           return frames;
515         }
516     }
517 }
518
519   public void setState (int state)
520   {
521     int current_state = getExtendedState ();
522
523     if (state == NORMAL
524         && (current_state & ICONIFIED) != 0)
525       setExtendedState (current_state | ICONIFIED);
526     
527     if (state == ICONIFIED
528         && (current_state & ~ICONIFIED) == 0)
529       setExtendedState (current_state & ~ICONIFIED);
530   }
531
532   public int getState ()
533   {
534     /* FIXME: State might have changed in the peer... Must check. */
535   
536     return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
537   }
538
539   /**
540    * @since 1.4
541    */
542   public void setExtendedState (int state)
543   {
544     this.state = state;
545   }
546
547   /**
548    * @since 1.4
549    */
550   public int getExtendedState ()
551   {
552     return state;
553   }
554
555   /**
556    * @since 1.4
557    */
558   public void setMaximizedBounds (Rectangle maximizedBounds)
559   {
560     this.maximizedBounds = maximizedBounds;
561   }
562
563   /**
564    * Returns the maximized bounds of this frame.
565    *
566    * @return the maximized rectangle, may be null.
567    *
568    * @since 1.4
569    */
570   public Rectangle getMaximizedBounds ()
571   {
572     return maximizedBounds;
573   }
574
575   /**
576    * Returns whether this frame is undecorated or not.
577    * 
578    * @since 1.4
579    */
580   public boolean isUndecorated ()
581   {
582     return undecorated;
583   }
584
585   /**
586    * Disables or enables decorations for this frame. This method can only be
587    * called while the frame is not displayable.
588    * 
589    * @exception IllegalComponentStateException If this frame is displayable.
590    * 
591    * @since 1.4
592    */
593   public void setUndecorated (boolean undecorated)
594   {
595     if (!isDisplayable ())
596       throw new IllegalComponentStateException ();
597
598     this.undecorated = undecorated;
599   }
600
601   /**
602    * Generate a unique name for this frame.
603    *
604    * @return A unique name for this frame.
605    */
606   String generateName ()
607   {
608     return "frame" + getUniqueLong ();
609   }
610
611   private static synchronized long getUniqueLong ()
612   {
613     return next_frame_number++;
614   }
615   
616   protected class AccessibleAWTFrame extends AccessibleAWTWindow
617   {
618     public AccessibleRole getAccessibleRole()
619     {
620       return AccessibleRole.FRAME;
621     }
622     
623     public AccessibleStateSet getAccessibleState()
624     {
625       AccessibleStateSet states = super.getAccessibleStateSet();
626       if (isResizable())
627         states.add(AccessibleState.RESIZABLE);
628       if ((state & ICONIFIED) != 0)
629         states.add(AccessibleState.ICONIFIED);
630       return states;
631     }
632   }
633   
634   /**
635    * Gets the AccessibleContext associated with this <code>Frame</code>.
636    * The context is created, if necessary.
637    *
638    * @return the associated context
639    */
640   public AccessibleContext getAccessibleContext()
641   {
642     /* Create the context if this is the first request */
643     if (accessibleContext == null)
644       accessibleContext = new AccessibleAWTFrame();
645     return accessibleContext;
646   }
647
648 }