home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / Window.java < prev    next >
Text File  |  1998-01-23  |  21KB  |  677 lines

  1. /*
  2.  * @(#)Window.java    1.66 97/08/20 Arthur van Hoff
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22. package java.awt;
  23.  
  24. import java.awt.peer.WindowPeer;
  25. import java.awt.event.*;
  26. import java.util.Vector;
  27. import java.util.Locale;
  28. import java.io.Serializable;
  29. import java.io.ObjectOutputStream;
  30. import java.io.ObjectInputStream;
  31. import java.io.IOException;
  32.  
  33.  
  34. /**
  35.  * A <code>Window</code> object is a top-level window with no borders and no
  36.  * menubar. It could be used to implement a pop-up menu.
  37.  * The default layout for a window is <code>BorderLayout</code>.
  38.  * A <code>Window</code> object blocks input to other application 
  39.  * windows when it is shown.
  40.  * <p>
  41.  * Windows are capable of generating the following window events:
  42.  * WindowOpened, WindowClosed.
  43.  *
  44.  * @version     1.66, 08/20/97
  45.  * @author     Sami Shaio
  46.  * @author     Arthur van Hoff
  47.  * @see WindowEvent
  48.  * @see #addWindowListener
  49.  * @see java.awt.BorderLayout
  50.  * @since       JDK1.0
  51.  */
  52. public class Window extends Container {
  53.     String      warningString;
  54.  
  55.     static final int OPENED = 0x01;
  56.     int state;
  57.     transient WindowListener windowListener;
  58.  
  59.     private FocusManager focusMgr;
  60.  
  61.     private static final String base = "win";
  62.     private static int nameCounter = 0;
  63.  
  64.     /*
  65.      * JDK 1.1 serialVersionUID 
  66.      */
  67.     private static final long serialVersionUID = 4497834738069338734L;
  68.  
  69.     Window() {
  70.     this.name = base + nameCounter++;
  71.     SecurityManager sm = System.getSecurityManager();
  72.     if ((sm != null) && !sm.checkTopLevelWindow(this)) {
  73.         warningString = System.getProperty("awt.appletWarning",
  74.                            "Warning: Applet Window");
  75.     }
  76.     this.focusMgr = new FocusManager(this);
  77.     this.visible = false;
  78.     }
  79.  
  80.     /**
  81.      * Constructs a new invisible window.
  82.      * <p>
  83.      * The window is not initially visible. Call the <code>show</code> 
  84.      * method to cause the window to become visible.
  85.      * @param     parent   the main application frame.
  86.      * @see       java.awt.Window#show
  87.      * @see       java.awt.Component#setSize
  88.      * @since     JDK1.0
  89.      */
  90.     public Window(Frame parent) {
  91.     this();
  92.     if (parent == null) {
  93.         throw new IllegalArgumentException("null parent frame");
  94.     }    
  95.     this.parent = parent;
  96.     parent.addOwnedWindow(this);
  97.     setLayout(new BorderLayout());
  98.     }
  99.  
  100.     /**
  101.      * Creates the Window's peer.  The peer allows us to modify the
  102.      * appearance of the Window without changing its functionality.
  103.      */
  104.     public void addNotify() {
  105.     if (peer == null) {
  106.         peer = getToolkit().createWindow(this);
  107.     }
  108.     super.addNotify();
  109.     }
  110.  
  111.     /**
  112.      * Causes subcomponents of this window to be laid out at their
  113.      * preferred size.
  114.      * @since     JDK1.0
  115.      */
  116.     public void pack() {
  117.     Container parent = this.parent;
  118.     if (parent != null && parent.getPeer() == null) {
  119.         parent.addNotify();
  120.     }
  121.     if (peer == null) {
  122.         addNotify();
  123.     }
  124.     setSize(getPreferredSize());
  125.     validate();
  126.     }
  127.  
  128.     /**
  129.      * Shows this window, and brings it to the front.
  130.      * <p>
  131.      * If this window is not yet visible, <code>show</code> 
  132.      * makes it visible. If this window is already visible, 
  133.      * then this method brings it to the front. 
  134.      * @see       java.awt.Window#toFront
  135.      * @see       java.awt.Component#setVisible
  136.      * @since     JDK1.0
  137.      */
  138.     public void show() {
  139.         Container parent = this.parent;
  140.     if (parent != null && parent.getPeer() == null) {
  141.         parent.addNotify();
  142.     }
  143.     if (peer == null) {
  144.         addNotify();
  145.     }
  146.     validate();
  147.  
  148.     if (visible) {
  149.         toFront();
  150.     } else {
  151.         super.show();
  152.     }
  153.         
  154.         // If first time shown, generate WindowOpened event
  155.         if ((state & OPENED) == 0) {
  156.             postWindowEvent(WindowEvent.WINDOW_OPENED);
  157.             state |= OPENED;
  158.         }
  159.     }
  160.  
  161.     synchronized void postWindowEvent(int id) {
  162.         if (windowListener != null || 
  163.             (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) {
  164.             WindowEvent e = new WindowEvent(this, id);
  165.             Toolkit.getEventQueue().postEvent(e);
  166.         }
  167.     }
  168.         
  169.     /**
  170.      * Disposes of this window. This method must
  171.      * be called to release the resources that
  172.      * are used for the window.
  173.      * @since JDK1.0
  174.      */
  175.     public void dispose() {
  176.     hide();
  177.     removeNotify();
  178.      if (parent != null) {
  179.         Frame parent = (Frame) this.parent;
  180.         parent.removeOwnedWindow(this);
  181.      } 
  182.         postWindowEvent(WindowEvent.WINDOW_CLOSED);
  183.     }
  184.  
  185.     /**
  186.      * Brings this window to the front.
  187.      * Places this window at the top of the stacking order and
  188.      * shows it in front of any other windows.
  189.      * @see       java.awt.Window#toBack
  190.      * @since     JDK1.0
  191.      */
  192.     public void toFront() {
  193.         WindowPeer peer = (WindowPeer)this.peer;
  194.     if (peer != null) {
  195.         peer.toFront();
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Sends this window to the back.
  201.      * Places this window at the bottom of the stacking order and
  202.      * makes the corresponding adjustment to other visible windows.
  203.      * @see       java.awt.Window#toFront
  204.      * @since     JDK1.0
  205.      */
  206.     public void toBack() {
  207.         WindowPeer peer = (WindowPeer)this.peer;
  208.     if (peer != null) {
  209.         peer.toBack();
  210.     }
  211.     }
  212.  
  213.     /**
  214.      * Returns the toolkit of this frame.
  215.      * @return    the toolkit of this window.
  216.      * @see       java.awt.Toolkit
  217.      * @see       java.awt.Toolkit#getDefaultToolkit()
  218.      * @see       java.awt.Component#getToolkit()
  219.      * @since     JDK1.0
  220.      */
  221.     public Toolkit getToolkit() {
  222.     return Toolkit.getDefaultToolkit();
  223.     }
  224.  
  225.     /**
  226.      * Gets the warning string that is displayed with this window. 
  227.      * If this window is insecure, the warning string is displayed 
  228.      * somewhere in the visible area of the window. A window is 
  229.      * insecure if there is a security manager, and the security 
  230.      * manager's <code>checkTopLevelWindow</code> method returns 
  231.      * <code>false</code> when this window is passed to it as an
  232.      * argument.
  233.      * <p>
  234.      * If the window is secure, then <code>getWarningString</code>
  235.      * returns <code>null</code>. If the window is insecure, this
  236.      * methods checks for the system property 
  237.      * <code>awt.appletWarning</code> 
  238.      * and returns the string value of that property. 
  239.      * @return    the warning string for this window.
  240.      * @see       java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
  241.      * @since     JDK1.0
  242.      */
  243.     public final String getWarningString() {
  244.     return warningString;
  245.     }
  246.  
  247.     /** 
  248.      * Gets the <code>Locale</code> object that is associated 
  249.      * with this window, if the locale has been set.
  250.      * If no locale has been set, then the default locale 
  251.      * is returned.
  252.      * @return    the locale that is set for this window.
  253.      * @see       java.util.Locale
  254.      * @since     JDK1.1
  255.      */
  256.  
  257.     public Locale getLocale() {
  258.       if (this.locale == null) {
  259.     return Locale.getDefault();
  260.       }
  261.       return this.locale;
  262.     }
  263.  
  264.     /**
  265.      * Adds the specified window listener to receive window events from
  266.      * this window.
  267.      * @param l the window listener
  268.      */ 
  269.     public synchronized void addWindowListener(WindowListener l) {
  270.         windowListener = AWTEventMulticaster.add(windowListener, l);
  271.         newEventsOnly = true;
  272.     }
  273.  
  274.     /**
  275.      * Removes the specified window listener so that it no longer
  276.      * receives window events from this window.
  277.      * @param l the window listener
  278.      */ 
  279.     public synchronized void removeWindowListener(WindowListener l) {
  280.         windowListener = AWTEventMulticaster.remove(windowListener, l);
  281.     }
  282.  
  283.     // REMIND: remove when filtering is handled at lower level
  284.     boolean eventEnabled(AWTEvent e) {
  285.         switch(e.id) {
  286.           case WindowEvent.WINDOW_OPENED:
  287.           case WindowEvent.WINDOW_CLOSING:
  288.           case WindowEvent.WINDOW_CLOSED:
  289.           case WindowEvent.WINDOW_ICONIFIED:
  290.           case WindowEvent.WINDOW_DEICONIFIED:
  291.           case WindowEvent.WINDOW_ACTIVATED:
  292.           case WindowEvent.WINDOW_DEACTIVATED:
  293.             if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
  294.                 windowListener != null) {
  295.                 return true;
  296.             }
  297.             return false;
  298.           default:
  299.             break;
  300.         }
  301.         return super.eventEnabled(e);
  302.     }
  303.  
  304.     /**
  305.      * Processes events on this window. If the event is an WindowEvent,
  306.      * it invokes the processWindowEvent method, else it invokes its
  307.      * superclass's processEvent.
  308.      * @param e the event
  309.      */
  310.     protected void processEvent(AWTEvent e) {
  311.         if (e instanceof WindowEvent) {
  312.             processWindowEvent((WindowEvent)e);
  313.             return;
  314.         }
  315.     super.processEvent(e);
  316.     }
  317.  
  318.     /** 
  319.      * Processes window events occurring on this window by
  320.      * dispatching them to any registered WindowListener objects.
  321.      * NOTE: This method will not be called unless window events
  322.      * are enabled for this component; this happens when one of the
  323.      * following occurs:
  324.      * a) A WindowListener object is registered via addWindowListener()
  325.      * b) Window events are enabled via enableEvents()
  326.      * @see Component#enableEvents
  327.      * @param e the window event
  328.      */  
  329.     protected void processWindowEvent(WindowEvent e) {
  330.         if (windowListener != null) {
  331.             switch(e.getID()) {
  332.               case WindowEvent.WINDOW_OPENED:
  333.                 windowListener.windowOpened(e);
  334.                 break;
  335.               case WindowEvent.WINDOW_CLOSING:
  336.                 windowListener.windowClosing(e);
  337.                 break;
  338.               case WindowEvent.WINDOW_CLOSED:
  339.                 windowListener.windowClosed(e);
  340.                 break;
  341.               case WindowEvent.WINDOW_ICONIFIED:
  342.                 windowListener.windowIconified(e);
  343.                 break;
  344.               case WindowEvent.WINDOW_DEICONIFIED:
  345.                 windowListener.windowDeiconified(e);
  346.                 break;
  347.               case WindowEvent.WINDOW_ACTIVATED:
  348.                 windowListener.windowActivated(e);
  349.                 break;
  350.               case WindowEvent.WINDOW_DEACTIVATED:
  351.                 windowListener.windowDeactivated(e);
  352.                 break;
  353.               default:
  354.                 break;
  355.             }
  356.         }
  357.     }
  358.  
  359.     /* Handle TAB and Shift-TAB events. */
  360.     private boolean handleTabEvent(KeyEvent e) {
  361.         if (e.getKeyCode() != '\t' || (e.getSource() instanceof TextArea)) {
  362.             return false;
  363.         }
  364.     if ((e.getModifiers() & ~InputEvent.SHIFT_MASK) > 0) {
  365.         return false;
  366.     }
  367.         int id = e.getID();
  368.     if (id == KeyEvent.KEY_RELEASED || id == KeyEvent.KEY_TYPED) {
  369.         return true;
  370.     }
  371.     if (e.isShiftDown()) {
  372.         return focusMgr.focusPrevious();
  373.     } else {
  374.         return focusMgr.focusNext();
  375.     }
  376.     }
  377.  
  378.     void preProcessKeyEvent(KeyEvent e) {
  379.         // Dump the list of child windows to System.out.
  380.         if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
  381.             e.isControlDown() && e.isShiftDown()) {
  382.             list(System.out, 0);
  383.         }
  384.     }
  385.  
  386.     void postProcessKeyEvent(KeyEvent e) {
  387.         if (handleTabEvent(e)) {
  388.             e.consume();
  389.             return;
  390.         }
  391.     }
  392.  
  393.     void setFocusOwner(Component c) {
  394.     focusMgr.setFocusOwner(c);
  395.     }
  396.  
  397.     void transferFocus(Component base) {
  398.     nextFocus(base);
  399.     }
  400.  
  401.     /**
  402.      * Returns the child component of this Window which has focus if and 
  403.      * only if this Window is active.
  404.      * @return the component with focus, or null if no children have focus
  405.      * assigned to them.
  406.      */
  407.     public Component getFocusOwner() {
  408.         return focusMgr.getFocusOwner();
  409.     }
  410.  
  411.     /**
  412.      * @deprecated As of JDK version 1.1,
  413.      * replaced by <code>transferFocus(Component)</code>.
  414.      */
  415.     void nextFocus(Component base) {
  416.     focusMgr.focusNext(base);
  417.     }
  418.  
  419.     /*
  420.      * Dispatches an event to this window or one of its sub components.
  421.      * @param e the event
  422.      */
  423.     void dispatchEventImpl(AWTEvent e) {
  424.         switch(e.getID()) {
  425.           case FocusEvent.FOCUS_GAINED:
  426.             setFocusOwner(this);
  427.             break;
  428.           case ComponentEvent.COMPONENT_RESIZED:
  429.             invalidate();
  430.             validate();
  431.             repaint();
  432.             break;
  433. /*
  434.   Calling this messes up focus on Solaris
  435.  
  436.           case WindowEvent.WINDOW_ACTIVATED:
  437.             focusMgr.activateFocus();
  438.             break;
  439. */
  440.           default:
  441.             break;
  442.         }
  443.         super.dispatchEventImpl(e);
  444.     }
  445.  
  446.     /**
  447.      * @deprecated As of JDK version 1.1
  448.      * replaced by <code>dispatchEvent(AWTEvent)</code>.
  449.      */
  450.     public boolean postEvent(Event e) {
  451.         if (handleEvent(e)) {
  452.             e.consume();
  453.             return true;
  454.         }
  455.         return false;
  456.     }
  457.  
  458.     /**
  459.      * Checks if this Window is showing on screen.
  460.      * @see java.awt.Component#setVisible(boolean)
  461.      */
  462.     public boolean isShowing() {
  463.     return visible;
  464.     }
  465.  
  466.     /* Serialization support.  If there's a MenuBar we restore
  467.      * its (transient) parent field here.
  468.      */
  469.  
  470.     private int windowSerializedDataVersion = 1;
  471.  
  472.  
  473.     private void writeObject(ObjectOutputStream s)
  474.       throws IOException 
  475.     {
  476.       s.defaultWriteObject();
  477.  
  478.       AWTEventMulticaster.save(s, windowListenerK, windowListener);
  479.       s.writeObject(null);
  480.     }
  481.  
  482.  
  483.     private void readObject(ObjectInputStream s)
  484.       throws ClassNotFoundException, IOException 
  485.     {
  486.       s.defaultReadObject();
  487.  
  488.       Object keyOrNull;
  489.       while(null != (keyOrNull = s.readObject())) {
  490.     String key = ((String)keyOrNull).intern();
  491.  
  492.     if (windowListenerK == key) 
  493.       addWindowListener((WindowListener)(s.readObject()));
  494.  
  495.     else // skip value for unrecognized key
  496.       s.readObject();
  497.       }
  498.     }
  499.  
  500. }
  501.  
  502.  
  503. class FocusManager implements java.io.Serializable {
  504.     Container focusRoot;
  505.     Component focusOwner;
  506.  
  507.     /*
  508.      * JDK 1.1 serialVersionUID 
  509.      */
  510.     static final long serialVersionUID = 2491878825643557906L;
  511.  
  512.     FocusManager(Container cont) {
  513.     focusRoot = cont;
  514.     }
  515.  
  516.     /* Re-activate the last component with focus if it is still
  517.      * visible and active.
  518.      * If no component had focus yet, assign it to first component
  519.      * capable of receiving it (visible, active, focusable).
  520.      * If no visible, active, focusable components are present,
  521.      * assign focus to the focus root.
  522.      */
  523.     void activateFocus() {
  524.         boolean assigned = false;
  525.         if (focusOwner != null) {
  526.             if ((assigned = assignFocus(focusOwner, false)) != true) {
  527.                 assigned = focusNext(focusOwner);
  528.             }
  529.         } else {
  530.             // assign to first component capable of taking it
  531.             assigned = focusForward(focusRoot);
  532.         }
  533.         if (!assigned) {
  534.             focusRoot.requestFocus(); 
  535.         }
  536.     }                
  537.                 
  538.      
  539.     synchronized void setFocusOwner(Component c) {
  540.         //System.out.println("FocusManager.setFocusOwner: "+c.name);
  541.         focusOwner = c;
  542.     }
  543.  
  544.     Component getFocusOwner() {
  545.        return focusOwner;
  546.     }
  547.     
  548.     boolean focusNext() {
  549.        return focusNext(focusOwner);
  550.     }
  551.  
  552.     boolean focusNext(Component base) {
  553.         synchronized (Component.LOCK) { // BUGID4067845
  554.             Component target = base;
  555.             if (target != null && target.parent != null) {
  556.                 //System.out.println("FocusManager.focusNext: owner="+focusOwner);
  557.                 do {
  558.                     boolean found = false;
  559.                     Container p = target.parent;
  560.                     Component c;
  561.                     for (int i = 0; i < p.ncomponents; i++) {
  562.                         c = p.component[i];
  563.                         if (found) {
  564.                             if (assignFocus(c)) {
  565.                                 return true;
  566.                             }
  567.                             if (c instanceof Container && 
  568.                                     c.isVisible() && 
  569.                                     c.isEnabled()) {
  570.                                 if (focusForward((Container)c)) {
  571.                                     return true;
  572.                                 }
  573.                             }         
  574.                         } else if (c == target) {
  575.                             found = true;    
  576.                         }
  577.                     } 
  578.                     target = p;
  579.                 } while (target != focusRoot && target.parent != null);
  580.             }
  581.             // wrap-around
  582.             if (focusForward(focusRoot)) {
  583.                 return true;
  584.             }
  585.     
  586.             return false;        
  587.         }
  588.     }
  589.  
  590.  
  591.     boolean focusPrevious() {
  592.         return focusPrevious(focusOwner);
  593.     }
  594.     
  595.     boolean focusPrevious(Component base) {
  596.         synchronized (Component.LOCK) { // BUGID4067845
  597.             Component target = base;
  598.             if (target != null && target.parent != null) {
  599.                 do {
  600.                     boolean found = false;
  601.                     Container p = target.parent;
  602.                         Component c;
  603.                     for (int i = p.ncomponents-1; i >= 0; i--) {
  604.                         c = p.component[i];
  605.                         if (found) {
  606.                             if (assignFocus(c)) {
  607.                                 return true;
  608.                             }
  609.                             if (c instanceof Container && 
  610.                                     c.isVisible() && 
  611.                                     c.isEnabled()) {
  612.                                 if (focusBackward((Container)c)) {
  613.                                     return true;
  614.                                 }
  615.                              }         
  616.                          } else if (c == target) {
  617.                              found = true;    
  618.                          }
  619.                     } 
  620.                     target = p;
  621.                 } while (target != focusRoot);
  622.  
  623.             }
  624.                             // wrap-around
  625.             if (focusBackward(focusRoot)) {
  626.                 return true;
  627.             }
  628.             return false;        
  629.         }
  630.     }
  631.  
  632.     boolean assignFocus(Component c) {
  633.         return assignFocus(c, true);
  634.     }
  635.  
  636.     synchronized boolean assignFocus(Component c, boolean requireTraversable) {
  637.         if (c.isVisible() && c.isEnabled() &&
  638.             (!requireTraversable || c.isFocusTraversable())) {
  639.             //System.out.println("FocusManager.assignFocus: "+c);
  640.             c.requestFocus();
  641.             return true;
  642.         }
  643.         return false;
  644.     }
  645.  
  646.     synchronized boolean focusForward(Container cont) {
  647.         for (int i = 0; i < cont.ncomponents; i++) {
  648.             Component c = cont.component[i];
  649.             if (assignFocus(c)) {
  650.                 return true;
  651.             }
  652.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  653.                 if (focusForward((Container)c)) {
  654.                     return true;
  655.                 }
  656.             } 
  657.         }
  658.         return false;
  659.     }
  660.  
  661.     synchronized boolean focusBackward(Container cont) {
  662.         for (int i = cont.ncomponents-1; i >= 0; i--) {
  663.             Component c = cont.component[i];
  664.             if (assignFocus(c)) {
  665.                 return true;
  666.             }
  667.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  668.                 if (focusBackward((Container)c)) {
  669.                     return true;
  670.                 }
  671.             } 
  672.         }
  673.         return false;
  674.     }
  675.  
  676. }
  677.