home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / Window.java < prev   
Encoding:
Java Source  |  1998-03-20  |  22.4 KB  |  789 lines

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