diff options
Diffstat (limited to 'libjava/classpath/java/awt/Container.java')
-rw-r--r-- | libjava/classpath/java/awt/Container.java | 2370 |
1 files changed, 0 insertions, 2370 deletions
diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java deleted file mode 100644 index 7e596f1..0000000 --- a/libjava/classpath/java/awt/Container.java +++ /dev/null @@ -1,2370 +0,0 @@ -/* Container.java -- parent container class in AWT - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.awt; - -import gnu.java.lang.CPStringBuilder; - -import java.awt.event.ContainerEvent; -import java.awt.event.ContainerListener; -import java.awt.event.HierarchyEvent; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; -import java.awt.peer.ComponentPeer; -import java.awt.peer.ContainerPeer; -import java.awt.peer.LightweightPeer; -import java.beans.PropertyChangeListener; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Serializable; -import java.util.Collections; -import java.util.EventListener; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import javax.accessibility.Accessible; - -/** - * A generic window toolkit object that acts as a container for other objects. - * Components are tracked in a list, and new elements are at the end of the - * list or bottom of the stacking order. - * - * @author original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * - * @since 1.0 - * - * @status still missing 1.4 support, some generics from 1.5 - */ -public class Container extends Component -{ - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 4613797578919906343L; - - /* Serialized fields from the serialization spec. */ - int ncomponents; - Component[] component; - LayoutManager layoutMgr; - - /** - * @since 1.4 - */ - boolean focusCycleRoot; - - /** - * Indicates if this container provides a focus traversal policy. - * - * @since 1.5 - */ - private boolean focusTraversalPolicyProvider; - - int containerSerializedDataVersion; - - /* Anything else is non-serializable, and should be declared "transient". */ - transient ContainerListener containerListener; - - /** The focus traversal policy that determines how focus is - transferred between this Container and its children. */ - private FocusTraversalPolicy focusTraversalPolicy; - - /** - * The focus traversal keys, if not inherited from the parent or default - * keyboard manager. These sets will contain only AWTKeyStrokes that - * represent press and release events to use as focus control. - * - * @see #getFocusTraversalKeys(int) - * @see #setFocusTraversalKeys(int, Set) - * @since 1.4 - */ - transient Set[] focusTraversalKeys; - - /** - * Default constructor for subclasses. - */ - public Container() - { - // Nothing to do here. - } - - /** - * Returns the number of components in this container. - * - * @return The number of components in this container. - */ - public int getComponentCount() - { - return countComponents (); - } - - /** - * Returns the number of components in this container. - * - * @return The number of components in this container. - * - * @deprecated use {@link #getComponentCount()} instead - */ - public int countComponents() - { - return ncomponents; - } - - /** - * Returns the component at the specified index. - * - * @param n The index of the component to retrieve. - * - * @return The requested component. - * - * @throws ArrayIndexOutOfBoundsException If the specified index is invalid - */ - public Component getComponent(int n) - { - synchronized (getTreeLock ()) - { - if (n < 0 || n >= ncomponents) - throw new ArrayIndexOutOfBoundsException("no such component"); - - return component[n]; - } - } - - /** - * Returns an array of the components in this container. - * - * @return The components in this container. - */ - public Component[] getComponents() - { - synchronized (getTreeLock ()) - { - Component[] result = new Component[ncomponents]; - - if (ncomponents > 0) - System.arraycopy(component, 0, result, 0, ncomponents); - - return result; - } - } - - /** - * Returns the insets for this container, which is the space used for - * borders, the margin, etc. - * - * @return The insets for this container. - */ - public Insets getInsets() - { - return insets (); - } - - /** - * Returns the insets for this container, which is the space used for - * borders, the margin, etc. - * - * @return The insets for this container. - * @deprecated use {@link #getInsets()} instead - */ - public Insets insets() - { - Insets i; - if (peer == null || peer instanceof LightweightPeer) - i = new Insets (0, 0, 0, 0); - else - i = ((ContainerPeer) peer).getInsets (); - return i; - } - - /** - * Adds the specified component to this container at the end of the - * component list. - * - * @param comp The component to add to the container. - * - * @return The same component that was added. - */ - public Component add(Component comp) - { - addImpl(comp, null, -1); - return comp; - } - - /** - * Adds the specified component to the container at the end of the - * component list. This method should not be used. Instead, use - * <code>add(Component, Object)</code>. - * - * @param name The name of the component to be added. - * @param comp The component to be added. - * - * @return The same component that was added. - * - * @see #add(Component,Object) - */ - public Component add(String name, Component comp) - { - addImpl(comp, name, -1); - return comp; - } - - /** - * Adds the specified component to this container at the specified index - * in the component list. - * - * @param comp The component to be added. - * @param index The index in the component list to insert this child - * at, or -1 to add at the end of the list. - * - * @return The same component that was added. - * - * @throws ArrayIndexOutOfBoundsException If the specified index is invalid. - */ - public Component add(Component comp, int index) - { - addImpl(comp, null, index); - return comp; - } - - /** - * Adds the specified component to this container at the end of the - * component list. The layout manager will use the specified constraints - * when laying out this component. - * - * @param comp The component to be added to this container. - * @param constraints The layout constraints for this component. - */ - public void add(Component comp, Object constraints) - { - addImpl(comp, constraints, -1); - } - - /** - * Adds the specified component to this container at the specified index - * in the component list. The layout manager will use the specified - * constraints when layout out this component. - * - * @param comp The component to be added. - * @param constraints The layout constraints for this component. - * @param index The index in the component list to insert this child - * at, or -1 to add at the end of the list. - * - * @throws ArrayIndexOutOfBoundsException If the specified index is invalid. - */ - public void add(Component comp, Object constraints, int index) - { - addImpl(comp, constraints, index); - } - - /** - * This method is called by all the <code>add()</code> methods to perform - * the actual adding of the component. Subclasses who wish to perform - * their own processing when a component is added should override this - * method. Any subclass doing this must call the superclass version of - * this method in order to ensure proper functioning of the container. - * - * @param comp The component to be added. - * @param constraints The layout constraints for this component, or - * <code>null</code> if there are no constraints. - * @param index The index in the component list to insert this child - * at, or -1 to add at the end of the list. - * - * @throws ArrayIndexOutOfBoundsException If the specified index is invalid. - */ - protected void addImpl(Component comp, Object constraints, int index) - { - synchronized (getTreeLock ()) - { - if (index > ncomponents - || (index < 0 && index != -1) - || comp instanceof Window - || (comp instanceof Container - && ((Container) comp).isAncestorOf(this))) - throw new IllegalArgumentException(); - - // Reparent component, and make sure component is instantiated if - // we are. - if (comp.parent != null) - comp.parent.remove(comp); - - if (component == null) - component = new Component[4]; // FIXME, better initial size? - - // This isn't the most efficient implementation. We could do less - // copying when growing the array. It probably doesn't matter. - if (ncomponents >= component.length) - { - int nl = component.length * 2; - Component[] c = new Component[nl]; - System.arraycopy(component, 0, c, 0, ncomponents); - component = c; - } - - if (index == -1) - component[ncomponents++] = comp; - else - { - System.arraycopy(component, index, component, index + 1, - ncomponents - index); - component[index] = comp; - ++ncomponents; - } - - // Give the new component a parent. - comp.parent = this; - - // Update the counter for Hierarchy(Bounds)Listeners. - int childHierarchyListeners = comp.numHierarchyListeners; - if (childHierarchyListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK, - childHierarchyListeners); - int childHierarchyBoundsListeners = comp.numHierarchyBoundsListeners; - if (childHierarchyBoundsListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, - childHierarchyListeners); - - // Invalidate the layout of this container. - if (valid) - invalidate(); - - // Create the peer _after_ the component has been added, so that - // the peer gets to know about the component hierarchy. - if (peer != null) - { - // Notify the component that it has a new parent. - comp.addNotify(); - } - - // Notify the layout manager. - if (layoutMgr != null) - { - // If we have a LayoutManager2 the constraints are "real", - // otherwise they are the "name" of the Component to add. - if (layoutMgr instanceof LayoutManager2) - { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - lm2.addLayoutComponent(comp, constraints); - } - else if (constraints instanceof String) - layoutMgr.addLayoutComponent((String) constraints, comp); - else - layoutMgr.addLayoutComponent("", comp); - } - - // We previously only sent an event when this container is showing. - // Also, the event was posted to the event queue. A Mauve test shows - // that this event is not delivered using the event queue and it is - // also sent when the container is not showing. - if (containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0) - { - ContainerEvent ce = new ContainerEvent(this, - ContainerEvent.COMPONENT_ADDED, - comp); - dispatchEvent(ce); - } - - // Notify hierarchy listeners. - comp.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, comp, - this, HierarchyEvent.PARENT_CHANGED); - } - } - - /** - * Removes the component at the specified index from this container. - * - * @param index The index of the component to remove. - */ - public void remove(int index) - { - synchronized (getTreeLock ()) - { - if (index < 0 || index >= ncomponents) - throw new ArrayIndexOutOfBoundsException(); - - Component r = component[index]; - if (peer != null) - r.removeNotify(); - - if (layoutMgr != null) - layoutMgr.removeLayoutComponent(r); - - // Update the counter for Hierarchy(Bounds)Listeners. - int childHierarchyListeners = r.numHierarchyListeners; - if (childHierarchyListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK, - -childHierarchyListeners); - int childHierarchyBoundsListeners = r.numHierarchyBoundsListeners; - if (childHierarchyBoundsListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, - -childHierarchyListeners); - - r.parent = null; - - System.arraycopy(component, index + 1, component, index, - ncomponents - index - 1); - component[--ncomponents] = null; - - if (valid) - invalidate(); - - if (containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0) - { - // Post event to notify of removing the component. - ContainerEvent ce = new ContainerEvent(this, - ContainerEvent.COMPONENT_REMOVED, - r); - dispatchEvent(ce); - } - - // Notify hierarchy listeners. - r.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, r, - this, HierarchyEvent.PARENT_CHANGED); - } - } - - /** - * Removes the specified component from this container. - * - * @param comp The component to remove from this container. - */ - public void remove(Component comp) - { - synchronized (getTreeLock ()) - { - for (int i = 0; i < ncomponents; ++i) - { - if (component[i] == comp) - { - remove(i); - break; - } - } - } - } - - /** - * Removes all components from this container. - */ - public void removeAll() - { - synchronized (getTreeLock ()) - { - // In order to allow the same bad tricks to be used as in RI - // this code has to stay exactly that way: In a real-life app - // a Container subclass implemented its own vector for - // subcomponents, supplied additional addXYZ() methods - // and overrode remove(int) and removeAll (the latter calling - // super.removeAll() ). - // By doing it this way, user code cannot prevent the correct - // removal of components. - while (ncomponents > 0) - { - ncomponents--; - Component r = component[ncomponents]; - component[ncomponents] = null; - - if (peer != null) - r.removeNotify(); - - if (layoutMgr != null) - layoutMgr.removeLayoutComponent(r); - - r.parent = null; - - // Send ContainerEvent if necessary. - if (containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0) - { - // Post event to notify of removing the component. - ContainerEvent ce - = new ContainerEvent(this, - ContainerEvent.COMPONENT_REMOVED, - r); - dispatchEvent(ce); - } - - // Update the counter for Hierarchy(Bounds)Listeners. - int childHierarchyListeners = r.numHierarchyListeners; - if (childHierarchyListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK, - -childHierarchyListeners); - int childHierarchyBoundsListeners = r.numHierarchyBoundsListeners; - if (childHierarchyBoundsListeners > 0) - updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, - -childHierarchyListeners); - - - // Send HierarchyEvent if necessary. - fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, r, this, - HierarchyEvent.PARENT_CHANGED); - - } - - if (valid) - invalidate(); - } - } - - /** - * Returns the current layout manager for this container. - * - * @return The layout manager for this container. - */ - public LayoutManager getLayout() - { - return layoutMgr; - } - - /** - * Sets the layout manager for this container to the specified layout - * manager. - * - * @param mgr The new layout manager for this container. - */ - public void setLayout(LayoutManager mgr) - { - layoutMgr = mgr; - if (valid) - invalidate(); - } - - /** - * Layout the components in this container. - */ - public void doLayout() - { - layout (); - } - - /** - * Layout the components in this container. - * - * @deprecated use {@link #doLayout()} instead - */ - public void layout() - { - if (layoutMgr != null) - layoutMgr.layoutContainer (this); - } - - /** - * Invalidates this container to indicate that it (and all parent - * containers) need to be laid out. - */ - public void invalidate() - { - super.invalidate(); - if (layoutMgr != null && layoutMgr instanceof LayoutManager2) - { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - lm2.invalidateLayout(this); - } - } - - /** - * Re-lays out the components in this container. - */ - public void validate() - { - ComponentPeer p = peer; - if (! valid && p != null) - { - ContainerPeer cPeer = null; - if (p instanceof ContainerPeer) - cPeer = (ContainerPeer) peer; - synchronized (getTreeLock ()) - { - if (cPeer != null) - cPeer.beginValidate(); - validateTree(); - valid = true; - if (cPeer != null) - cPeer.endValidate(); - } - } - } - - /** - * Recursively invalidates the container tree. - */ - private final void invalidateTree() - { - synchronized (getTreeLock()) - { - for (int i = 0; i < ncomponents; i++) - { - Component comp = component[i]; - if (comp instanceof Container) - ((Container) comp).invalidateTree(); - else if (comp.valid) - comp.invalidate(); - } - if (valid) - invalidate(); - } - } - - /** - * Recursively validates the container tree, recomputing any invalid - * layouts. - */ - protected void validateTree() - { - if (!valid) - { - ContainerPeer cPeer = null; - if (peer instanceof ContainerPeer) - { - cPeer = (ContainerPeer) peer; - cPeer.beginLayout(); - } - - doLayout (); - for (int i = 0; i < ncomponents; ++i) - { - Component comp = component[i]; - - if (comp instanceof Container && ! (comp instanceof Window) - && ! comp.valid) - { - ((Container) comp).validateTree(); - } - else - { - comp.validate(); - } - } - - if (cPeer != null) - { - cPeer = (ContainerPeer) peer; - cPeer.endLayout(); - } - } - - /* children will call invalidate() when they are layed out. It - is therefore important that valid is not set to true - until after the children have been layed out. */ - valid = true; - - } - - public void setFont(Font f) - { - Font oldFont = getFont(); - super.setFont(f); - Font newFont = getFont(); - if (newFont != oldFont && (oldFont == null || ! oldFont.equals(newFont))) - { - invalidateTree(); - } - } - - /** - * Returns the preferred size of this container. - * - * @return The preferred size of this container. - */ - public Dimension getPreferredSize() - { - return preferredSize (); - } - - /** - * Returns the preferred size of this container. - * - * @return The preferred size of this container. - * - * @deprecated use {@link #getPreferredSize()} instead - */ - public Dimension preferredSize() - { - Dimension size = prefSize; - // Try to return cached value if possible. - if (size == null || !(prefSizeSet || valid)) - { - // Need to lock here. - synchronized (getTreeLock()) - { - LayoutManager l = layoutMgr; - if (l != null) - prefSize = l.preferredLayoutSize(this); - else - prefSize = super.preferredSizeImpl(); - size = prefSize; - } - } - if (size != null) - return new Dimension(size); - else - return size; - } - - /** - * Returns the minimum size of this container. - * - * @return The minimum size of this container. - */ - public Dimension getMinimumSize() - { - return minimumSize (); - } - - /** - * Returns the minimum size of this container. - * - * @return The minimum size of this container. - * - * @deprecated use {@link #getMinimumSize()} instead - */ - public Dimension minimumSize() - { - Dimension size = minSize; - // Try to return cached value if possible. - if (size == null || !(minSizeSet || valid)) - { - // Need to lock here. - synchronized (getTreeLock()) - { - LayoutManager l = layoutMgr; - if (l != null) - minSize = l.minimumLayoutSize(this); - else - minSize = super.minimumSizeImpl(); - size = minSize; - } - } - if (size != null) - return new Dimension(size); - else - return size; - } - - /** - * Returns the maximum size of this container. - * - * @return The maximum size of this container. - */ - public Dimension getMaximumSize() - { - Dimension size = maxSize; - // Try to return cached value if possible. - if (size == null || !(maxSizeSet || valid)) - { - // Need to lock here. - synchronized (getTreeLock()) - { - LayoutManager l = layoutMgr; - if (l instanceof LayoutManager2) - maxSize = ((LayoutManager2) l).maximumLayoutSize(this); - else { - maxSize = super.maximumSizeImpl(); - } - size = maxSize; - } - } - if (size != null) - return new Dimension(size); - else - return size; - } - - /** - * Returns the preferred alignment along the X axis. This is a value - * between 0 and 1 where 0 represents alignment flush left and - * 1 means alignment flush right, and 0.5 means centered. - * - * @return The preferred alignment along the X axis. - */ - public float getAlignmentX() - { - LayoutManager layout = getLayout(); - float alignmentX = 0.0F; - if (layout != null && layout instanceof LayoutManager2) - { - synchronized (getTreeLock()) - { - LayoutManager2 lm2 = (LayoutManager2) layout; - alignmentX = lm2.getLayoutAlignmentX(this); - } - } - else - alignmentX = super.getAlignmentX(); - return alignmentX; - } - - /** - * Returns the preferred alignment along the Y axis. This is a value - * between 0 and 1 where 0 represents alignment flush top and - * 1 means alignment flush bottom, and 0.5 means centered. - * - * @return The preferred alignment along the Y axis. - */ - public float getAlignmentY() - { - LayoutManager layout = getLayout(); - float alignmentY = 0.0F; - if (layout != null && layout instanceof LayoutManager2) - { - synchronized (getTreeLock()) - { - LayoutManager2 lm2 = (LayoutManager2) layout; - alignmentY = lm2.getLayoutAlignmentY(this); - } - } - else - alignmentY = super.getAlignmentY(); - return alignmentY; - } - - /** - * Paints this container. The implementation of this method in this - * class forwards to any lightweight components in this container. If - * this method is subclassed, this method should still be invoked as - * a superclass method so that lightweight components are properly - * drawn. - * - * @param g - The graphics context for this paint job. - */ - public void paint(Graphics g) - { - if (isShowing()) - { - visitChildren(g, GfxPaintVisitor.INSTANCE, true); - } - } - - /** - * Updates this container. The implementation of this method in this - * class forwards to any lightweight components in this container. If - * this method is subclassed, this method should still be invoked as - * a superclass method so that lightweight components are properly - * drawn. - * - * @param g The graphics context for this update. - * - * @specnote The specification suggests that this method forwards the - * update() call to all its lightweight children. Tests show - * that this is not done either in the JDK. The exact behaviour - * seems to be that the background is cleared in heavyweight - * Containers, and all other containers - * directly call paint(), causing the (lightweight) children to - * be painted. - */ - public void update(Graphics g) - { - // It seems that the JDK clears the background of containers like Panel - // and Window (within this method) but not of 'plain' Containers or - // JComponents. This could - // lead to the assumption that it only clears heavyweight containers. - // However that is not quite true. In a test with a custom Container - // that overrides isLightweight() to return false, the background is - // also not cleared. So we do a check on !(peer instanceof LightweightPeer) - // instead. - if (isShowing()) - { - ComponentPeer p = peer; - if (! (p instanceof LightweightPeer)) - { - g.clearRect(0, 0, getWidth(), getHeight()); - } - paint(g); - } - } - - /** - * Prints this container. The implementation of this method in this - * class forwards to any lightweight components in this container. If - * this method is subclassed, this method should still be invoked as - * a superclass method so that lightweight components are properly - * drawn. - * - * @param g The graphics context for this print job. - */ - public void print(Graphics g) - { - super.print(g); - visitChildren(g, GfxPrintVisitor.INSTANCE, true); - } - - /** - * Paints all of the components in this container. - * - * @param g The graphics context for this paint job. - */ - public void paintComponents(Graphics g) - { - if (isShowing()) - visitChildren(g, GfxPaintAllVisitor.INSTANCE, false); - } - - /** - * Prints all of the components in this container. - * - * @param g The graphics context for this print job. - */ - public void printComponents(Graphics g) - { - super.paint(g); - visitChildren(g, GfxPrintAllVisitor.INSTANCE, true); - } - - /** - * Adds the specified container listener to this object's list of - * container listeners. - * - * @param listener The listener to add. - */ - public synchronized void addContainerListener(ContainerListener listener) - { - if (listener != null) - { - containerListener = AWTEventMulticaster.add(containerListener, - listener); - newEventsOnly = true; - } - } - - /** - * Removes the specified container listener from this object's list of - * container listeners. - * - * @param listener The listener to remove. - */ - public synchronized void removeContainerListener(ContainerListener listener) - { - containerListener = AWTEventMulticaster.remove(containerListener, listener); - } - - /** - * @since 1.4 - */ - public synchronized ContainerListener[] getContainerListeners() - { - return (ContainerListener[]) - AWTEventMulticaster.getListeners(containerListener, - ContainerListener.class); - } - - /** - * Returns all registered {@link EventListener}s of the given - * <code>listenerType</code>. - * - * @param listenerType the class of listeners to filter (<code>null</code> - * not permitted). - * - * @return An array of registered listeners. - * - * @throws ClassCastException if <code>listenerType</code> does not implement - * the {@link EventListener} interface. - * @throws NullPointerException if <code>listenerType</code> is - * <code>null</code>. - * - * @see #getContainerListeners() - * - * @since 1.3 - */ - public <T extends EventListener> T[] getListeners(Class<T> listenerType) - { - if (listenerType == ContainerListener.class) - return (T[]) getContainerListeners(); - return super.getListeners(listenerType); - } - - /** - * Processes the specified event. This method calls - * <code>processContainerEvent()</code> if this method is a - * <code>ContainerEvent</code>, otherwise it calls the superclass - * method. - * - * @param e The event to be processed. - */ - protected void processEvent(AWTEvent e) - { - if (e instanceof ContainerEvent) - processContainerEvent((ContainerEvent) e); - else - super.processEvent(e); - } - - /** - * Called when a container event occurs if container events are enabled. - * This method calls any registered listeners. - * - * @param e The event that occurred. - */ - protected void processContainerEvent(ContainerEvent e) - { - if (containerListener == null) - return; - switch (e.id) - { - case ContainerEvent.COMPONENT_ADDED: - containerListener.componentAdded(e); - break; - - case ContainerEvent.COMPONENT_REMOVED: - containerListener.componentRemoved(e); - break; - } - } - - /** - * AWT 1.0 event processor. - * - * @param e The event that occurred. - * - * @deprecated use {@link #dispatchEvent(AWTEvent)} instead - */ - public void deliverEvent(Event e) - { - if (!handleEvent (e)) - { - synchronized (getTreeLock ()) - { - Component parent = getParent (); - - if (parent != null) - parent.deliverEvent (e); - } - } - } - - /** - * Returns the component located at the specified point. This is done - * by checking whether or not a child component claims to contain this - * point. The first child component that does is returned. If no - * child component claims the point, the container itself is returned, - * unless the point does not exist within this container, in which - * case <code>null</code> is returned. - * - * When components overlap, the first component is returned. The component - * that is closest to (x, y), containing that location, is returned. - * Heavyweight components take precedence of lightweight components. - * - * This function does not ignore invisible components. If there is an invisible - * component at (x,y), it will be returned. - * - * @param x The X coordinate of the point. - * @param y The Y coordinate of the point. - * - * @return The component containing the specified point, or - * <code>null</code> if there is no such point. - */ - public Component getComponentAt(int x, int y) - { - return locate (x, y); - } - - /** - * Returns the mouse pointer position relative to this Container's - * top-left corner. If allowChildren is false, the mouse pointer - * must be directly over this container. If allowChildren is true, - * the mouse pointer may be over this container or any of its - * descendents. - * - * @param allowChildren true to allow descendents, false if pointer - * must be directly over Container. - * - * @return relative mouse pointer position - * - * @throws HeadlessException if in a headless environment - */ - public Point getMousePosition(boolean allowChildren) throws HeadlessException - { - return super.getMousePositionHelper(allowChildren); - } - - boolean mouseOverComponent(Component component, boolean allowChildren) - { - if (allowChildren) - return isAncestorOf(component); - else - return component == this; - } - - /** - * Returns the component located at the specified point. This is done - * by checking whether or not a child component claims to contain this - * point. The first child component that does is returned. If no - * child component claims the point, the container itself is returned, - * unless the point does not exist within this container, in which - * case <code>null</code> is returned. - * - * When components overlap, the first component is returned. The component - * that is closest to (x, y), containing that location, is returned. - * Heavyweight components take precedence of lightweight components. - * - * This function does not ignore invisible components. If there is an invisible - * component at (x,y), it will be returned. - * - * @param x The x position of the point to return the component at. - * @param y The y position of the point to return the component at. - * - * @return The component containing the specified point, or <code>null</code> - * if there is no such point. - * - * @deprecated use {@link #getComponentAt(int, int)} instead - */ - public Component locate(int x, int y) - { - synchronized (getTreeLock ()) - { - if (!contains (x, y)) - return null; - - // First find the component closest to (x,y) that is a heavyweight. - for (int i = 0; i < ncomponents; ++i) - { - Component comp = component[i]; - int x2 = x - comp.x; - int y2 = y - comp.y; - if (comp.contains (x2, y2) && !comp.isLightweight()) - return comp; - } - - // if a heavyweight component is not found, look for a lightweight - // closest to (x,y). - for (int i = 0; i < ncomponents; ++i) - { - Component comp = component[i]; - int x2 = x - comp.x; - int y2 = y - comp.y; - if (comp.contains (x2, y2) && comp.isLightweight()) - return comp; - } - - return this; - } - } - - /** - * Returns the component located at the specified point. This is done - * by checking whether or not a child component claims to contain this - * point. The first child component that does is returned. If no - * child component claims the point, the container itself is returned, - * unless the point does not exist within this container, in which - * case <code>null</code> is returned. - * - * The top-most child component is returned in the case where components overlap. - * This is determined by finding the component closest to (x,y) and contains - * that location. Heavyweight components take precedence of lightweight components. - * - * This function does not ignore invisible components. If there is an invisible - * component at (x,y), it will be returned. - * - * @param p The point to return the component at. - * @return The component containing the specified point, or <code>null</code> - * if there is no such point. - */ - public Component getComponentAt(Point p) - { - return getComponentAt (p.x, p.y); - } - - /** - * Locates the visible child component that contains the specified position. - * The top-most child component is returned in the case where there is overlap - * in the components. If the containing child component is a Container, - * this method will continue searching for the deepest nested child - * component. Components which are not visible are ignored during the search. - * - * findComponentAt differs from getComponentAt, because it recursively - * searches a Container's children. - * - * @param x - x coordinate - * @param y - y coordinate - * @return null if the component does not contain the position. - * If there is no child component at the requested point and the point is - * within the bounds of the container the container itself is returned. - */ - public Component findComponentAt(int x, int y) - { - synchronized (getTreeLock ()) - { - if (! contains(x, y)) - return null; - - for (int i = 0; i < ncomponents; ++i) - { - // Ignore invisible children... - if (!component[i].isVisible()) - continue; - - int x2 = x - component[i].x; - int y2 = y - component[i].y; - // We don't do the contains() check right away because - // findComponentAt would redundantly do it first thing. - if (component[i] instanceof Container) - { - Container k = (Container) component[i]; - Component r = k.findComponentAt(x2, y2); - if (r != null) - return r; - } - else if (component[i].contains(x2, y2)) - return component[i]; - } - - return this; - } - } - - /** - * Locates the visible child component that contains the specified position. - * The top-most child component is returned in the case where there is overlap - * in the components. If the containing child component is a Container, - * this method will continue searching for the deepest nested child - * component. Components which are not visible are ignored during the search. - * - * findComponentAt differs from getComponentAt, because it recursively - * searches a Container's children. - * - * @param p - the component's location - * @return null if the component does not contain the position. - * If there is no child component at the requested point and the point is - * within the bounds of the container the container itself is returned. - */ - public Component findComponentAt(Point p) - { - return findComponentAt(p.x, p.y); - } - - /** - * Called when this container is added to another container to inform it - * to create its peer. Peers for any child components will also be - * created. - */ - public void addNotify() - { - synchronized (getTreeLock()) - { - super.addNotify(); - addNotifyContainerChildren(); - } - } - - /** - * Called when this container is removed from its parent container to - * inform it to destroy its peer. This causes the peers of all child - * component to be destroyed as well. - */ - public void removeNotify() - { - synchronized (getTreeLock ()) - { - int ncomps = ncomponents; - Component[] comps = component; - for (int i = ncomps - 1; i >= 0; --i) - { - Component comp = comps[i]; - if (comp != null) - comp.removeNotify(); - } - super.removeNotify(); - } - } - - /** - * Tests whether or not the specified component is contained within - * this components subtree. - * - * @param comp The component to test. - * - * @return <code>true</code> if this container is an ancestor of the - * specified component, <code>false</code> otherwise. - */ - public boolean isAncestorOf(Component comp) - { - synchronized (getTreeLock ()) - { - while (true) - { - if (comp == null) - return false; - comp = comp.getParent(); - if (comp == this) - return true; - } - } - } - - /** - * Returns a string representing the state of this container for - * debugging purposes. - * - * @return A string representing the state of this container. - */ - protected String paramString() - { - if (layoutMgr == null) - return super.paramString(); - - CPStringBuilder sb = new CPStringBuilder(); - sb.append(super.paramString()); - sb.append(",layout="); - sb.append(layoutMgr.getClass().getName()); - return sb.toString(); - } - - /** - * Writes a listing of this container to the specified stream starting - * at the specified indentation point. - * - * @param out The <code>PrintStream</code> to write to. - * @param indent The indentation point. - */ - public void list(PrintStream out, int indent) - { - synchronized (getTreeLock ()) - { - super.list(out, indent); - for (int i = 0; i < ncomponents; ++i) - component[i].list(out, indent + 2); - } - } - - /** - * Writes a listing of this container to the specified stream starting - * at the specified indentation point. - * - * @param out The <code>PrintWriter</code> to write to. - * @param indent The indentation point. - */ - public void list(PrintWriter out, int indent) - { - synchronized (getTreeLock ()) - { - super.list(out, indent); - for (int i = 0; i < ncomponents; ++i) - component[i].list(out, indent + 2); - } - } - - /** - * Sets the focus traversal keys for a given traversal operation for this - * Container. - * - * @exception IllegalArgumentException If id is not one of - * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, - * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, - * or if keystrokes contains null, or if any Object in keystrokes is not an - * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event, or if any - * keystroke already maps to another focus traversal operation for this - * Container. - * - * @since 1.4 - */ - public void setFocusTraversalKeys(int id, - Set<? extends AWTKeyStroke> keystrokes) - { - if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS && - id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS) - throw new IllegalArgumentException (); - - if (keystrokes == null) - { - Container parent = getParent (); - - while (parent != null) - { - if (parent.areFocusTraversalKeysSet (id)) - { - keystrokes = parent.getFocusTraversalKeys (id); - break; - } - parent = parent.getParent (); - } - - if (keystrokes == null) - keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager (). - getDefaultFocusTraversalKeys (id); - } - - Set sa; - Set sb; - Set sc; - String name; - switch (id) - { - case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: - sa = getFocusTraversalKeys - (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); - sb = getFocusTraversalKeys - (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); - sc = getFocusTraversalKeys - (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS); - name = "forwardFocusTraversalKeys"; - break; - case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS: - sa = getFocusTraversalKeys - (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - sb = getFocusTraversalKeys - (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); - sc = getFocusTraversalKeys - (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS); - name = "backwardFocusTraversalKeys"; - break; - case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS: - sa = getFocusTraversalKeys - (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - sb = getFocusTraversalKeys - (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); - sc = getFocusTraversalKeys - (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS); - name = "upCycleFocusTraversalKeys"; - break; - case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS: - sa = getFocusTraversalKeys - (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - sb = getFocusTraversalKeys - (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); - sc = getFocusTraversalKeys - (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); - name = "downCycleFocusTraversalKeys"; - break; - default: - throw new IllegalArgumentException (); - } - - int i = keystrokes.size (); - Iterator iter = keystrokes.iterator (); - - while (--i >= 0) - { - Object o = iter.next (); - if (!(o instanceof AWTKeyStroke) - || sa.contains (o) || sb.contains (o) || sc.contains (o) - || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED) - throw new IllegalArgumentException (); - } - - if (focusTraversalKeys == null) - focusTraversalKeys = new Set[4]; - - keystrokes = - Collections.unmodifiableSet(new HashSet<AWTKeyStroke>(keystrokes)); - firePropertyChange (name, focusTraversalKeys[id], keystrokes); - - focusTraversalKeys[id] = keystrokes; - } - - /** - * Returns the Set of focus traversal keys for a given traversal operation for - * this Container. - * - * @exception IllegalArgumentException If id is not one of - * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, - * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS. - * - * @since 1.4 - */ - public Set<AWTKeyStroke> getFocusTraversalKeys (int id) - { - if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS && - id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS) - throw new IllegalArgumentException (); - - Set s = null; - - if (focusTraversalKeys != null) - s = focusTraversalKeys[id]; - - if (s == null && parent != null) - s = parent.getFocusTraversalKeys (id); - - return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager() - .getDefaultFocusTraversalKeys(id)) : s; - } - - /** - * Returns whether the Set of focus traversal keys for the given focus - * traversal operation has been explicitly defined for this Container. - * If this method returns false, this Container is inheriting the Set from - * an ancestor, or from the current KeyboardFocusManager. - * - * @exception IllegalArgumentException If id is not one of - * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, - * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, - * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS. - * - * @since 1.4 - */ - public boolean areFocusTraversalKeysSet (int id) - { - if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS && - id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS && - id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS) - throw new IllegalArgumentException (); - - return focusTraversalKeys != null && focusTraversalKeys[id] != null; - } - - /** - * Check whether the given Container is the focus cycle root of this - * Container's focus traversal cycle. If this Container is a focus - * cycle root itself, then it will be in two different focus cycles - * -- it's own, and that of its ancestor focus cycle root's. In - * that case, if <code>c</code> is either of those containers, this - * method will return true. - * - * @param c the candidate Container - * - * @return true if c is the focus cycle root of the focus traversal - * cycle to which this Container belongs, false otherwise - * - * @since 1.4 - */ - public boolean isFocusCycleRoot (Container c) - { - if (this == c - && isFocusCycleRoot ()) - return true; - - Container ancestor = getFocusCycleRootAncestor (); - - if (c == ancestor) - return true; - - return false; - } - - /** - * If this Container is a focus cycle root, set the focus traversal - * policy that determines the focus traversal order for its - * children. If non-null, this policy will be inherited by all - * inferior focus cycle roots. If <code>policy</code> is null, this - * Container will inherit its policy from the closest ancestor focus - * cycle root that's had its policy set. - * - * @param policy the new focus traversal policy for this Container or null - * - * @since 1.4 - */ - public void setFocusTraversalPolicy (FocusTraversalPolicy policy) - { - focusTraversalPolicy = policy; - } - - /** - * Return the focus traversal policy that determines the focus - * traversal order for this Container's children. This method - * returns null if this Container is not a focus cycle root. If the - * focus traversal policy has not been set explicitly, then this - * method will return an ancestor focus cycle root's policy instead. - * - * @return this Container's focus traversal policy or null - * - * @since 1.4 - */ - public FocusTraversalPolicy getFocusTraversalPolicy () - { - if (!isFocusCycleRoot ()) - return null; - - if (focusTraversalPolicy == null) - { - Container ancestor = getFocusCycleRootAncestor (); - - if (ancestor != this && ancestor != null) - return ancestor.getFocusTraversalPolicy (); - else - { - KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); - - return manager.getDefaultFocusTraversalPolicy (); - } - } - else - return focusTraversalPolicy; - } - - /** - * Check whether this Container's focus traversal policy has been - * explicitly set. If it has not, then this Container will inherit - * its focus traversal policy from one of its ancestor focus cycle - * roots. - * - * @return true if focus traversal policy is set, false otherwise - */ - public boolean isFocusTraversalPolicySet () - { - return focusTraversalPolicy == null; - } - - /** - * Set whether or not this Container is the root of a focus - * traversal cycle. This Container's focus traversal policy - * determines the order of focus traversal. Some policies prevent - * the focus from being transferred between two traversal cycles - * until an up or down traversal operation is performed. In that - * case, normal traversal (not up or down) is limited to this - * Container and all of this Container's descendents that are not - * descendents of inferior focus cycle roots. In the default case - * however, ContainerOrderFocusTraversalPolicy is in effect, and it - * supports implicit down-cycle traversal operations. - * - * @param focusCycleRoot true if this is a focus cycle root, false otherwise - * - * @since 1.4 - */ - public void setFocusCycleRoot (boolean focusCycleRoot) - { - this.focusCycleRoot = focusCycleRoot; - } - - /** - * Set to <code>true</code> if this container provides a focus traversal - * policy, <code>false</code> when the root container's focus - * traversal policy should be used. - * - * @return <code>true</code> if this container provides a focus traversal - * policy, <code>false</code> when the root container's focus - * traversal policy should be used - * - * @see #setFocusTraversalPolicyProvider(boolean) - * - * @since 1.5 - */ - public final boolean isFocusTraversalPolicyProvider() - { - return focusTraversalPolicyProvider; - } - - /** - * Set to <code>true</code> if this container provides a focus traversal - * policy, <code>false</code> when the root container's focus - * traversal policy should be used. - * - * @param b <code>true</code> if this container provides a focus traversal - * policy, <code>false</code> when the root container's focus - * traversal policy should be used - * - * @see #isFocusTraversalPolicyProvider() - * - * @since 1.5 - */ - public final void setFocusTraversalPolicyProvider(boolean b) - { - focusTraversalPolicyProvider = b; - } - - /** - * Check whether this Container is a focus cycle root. - * - * @return true if this is a focus cycle root, false otherwise - * - * @since 1.4 - */ - public boolean isFocusCycleRoot () - { - return focusCycleRoot; - } - - /** - * Transfer focus down one focus traversal cycle. If this Container - * is a focus cycle root, then its default component becomes the - * focus owner, and this Container becomes the current focus cycle - * root. No traversal will occur if this Container is not a focus - * cycle root. - * - * @since 1.4 - */ - public void transferFocusDownCycle () - { - if (isFocusCycleRoot()) - { - KeyboardFocusManager fm = - KeyboardFocusManager.getCurrentKeyboardFocusManager(); - fm.setGlobalCurrentFocusCycleRoot(this); - FocusTraversalPolicy policy = getFocusTraversalPolicy(); - Component defaultComponent = policy.getDefaultComponent(this); - if (defaultComponent != null) - defaultComponent.requestFocus(); - } - } - - /** - * Sets the ComponentOrientation property of this container and all components - * contained within it. - * - * @exception NullPointerException If orientation is null - * - * @since 1.4 - */ - public void applyComponentOrientation (ComponentOrientation orientation) - { - if (orientation == null) - throw new NullPointerException(); - - setComponentOrientation(orientation); - for (int i = 0; i < ncomponents; i++) - { - if (component[i] instanceof Container) - ((Container) component[i]).applyComponentOrientation(orientation); - else - component[i].setComponentOrientation(orientation); - } - } - - public void addPropertyChangeListener (PropertyChangeListener listener) - { - // TODO: Why is this overridden? - super.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener (String propertyName, - PropertyChangeListener listener) - { - // TODO: Why is this overridden? - super.addPropertyChangeListener(propertyName, listener); - } - - - /** - * Sets the Z ordering for the component <code>comp</code> to - * <code>index</code>. Components with lower Z order paint above components - * with higher Z order. - * - * @param comp the component for which to change the Z ordering - * @param index the index to set - * - * @throws NullPointerException if <code>comp == null</code> - * @throws IllegalArgumentException if comp is an ancestor of this container - * @throws IllegalArgumentException if <code>index</code> is not in - * <code>[0, getComponentCount()]</code> for moving between - * containers or <code>[0, getComponentCount() - 1]</code> for moving - * inside this container - * @throws IllegalArgumentException if <code>comp == this</code> - * @throws IllegalArgumentException if <code>comp</code> is a - * <code>Window</code> - * - * @see #getComponentZOrder(Component) - * - * @since 1.5 - */ - public final void setComponentZOrder(Component comp, int index) - { - if (comp == null) - throw new NullPointerException("comp must not be null"); - if (comp instanceof Container && ((Container) comp).isAncestorOf(this)) - throw new IllegalArgumentException("comp must not be an ancestor of " - + "this"); - if (comp instanceof Window) - throw new IllegalArgumentException("comp must not be a Window"); - - if (comp == this) - throw new IllegalArgumentException("cannot add component to itself"); - - synchronized (getTreeLock()) - { - // FIXME: Implement reparenting. - if ( comp.getParent() != this) - throw new AssertionError("Reparenting is not implemented yet"); - else - { - // Find current component index. - int currentIndex = getComponentZOrder(comp); - if (currentIndex < index) - { - System.arraycopy(component, currentIndex + 1, component, - currentIndex, index - currentIndex); - } - else - { - System.arraycopy(component, index, component, index + 1, - currentIndex - index); - } - component[index] = comp; - } - } - } - - /** - * Returns the Z ordering index of <code>comp</code>. If <code>comp</code> - * is not a child component of this Container, this returns <code>-1</code>. - * - * @param comp the component for which to query the Z ordering - * - * @return the Z ordering index of <code>comp</code> or <code>-1</code> if - * <code>comp</code> is not a child of this Container - * - * @see #setComponentZOrder(Component, int) - * - * @since 1.5 - */ - public final int getComponentZOrder(Component comp) - { - synchronized (getTreeLock()) - { - int index = -1; - if (component != null) - { - for (int i = 0; i < ncomponents; i++) - { - if (component[i] == comp) - { - index = i; - break; - } - } - } - return index; - } - } - - // Hidden helper methods. - - /** - * Perform a graphics operation on the children of this container. - * For each applicable child, the visitChild() method will be called - * to perform the graphics operation. - * - * @param gfx The graphics object that will be used to derive new - * graphics objects for the children. - * - * @param visitor Object encapsulating the graphics operation that - * should be performed. - * - * @param lightweightOnly If true, only lightweight components will - * be visited. - */ - private void visitChildren(Graphics gfx, GfxVisitor visitor, - boolean lightweightOnly) - { - synchronized (getTreeLock()) - { - for (int i = ncomponents - 1; i >= 0; --i) - { - Component comp = component[i]; - boolean applicable = comp.isVisible() - && (comp.isLightweight() || ! lightweightOnly); - - if (applicable) - visitChild(gfx, visitor, comp); - } - } - } - - /** - * Perform a graphics operation on a child. A translated and clipped - * graphics object will be created, and the visit() method of the - * visitor will be called to perform the operation. - * - * @param gfx The graphics object that will be used to derive new - * graphics objects for the child. - * - * @param visitor Object encapsulating the graphics operation that - * should be performed. - * - * @param comp The child component that should be visited. - */ - private void visitChild(Graphics gfx, GfxVisitor visitor, - Component comp) - { - Rectangle bounds = comp.getBounds(); - - if(!gfx.hitClip(bounds.x,bounds.y, bounds.width, bounds.height)) - return; - Graphics g2 = gfx.create(bounds.x, bounds.y, bounds.width, - bounds.height); - try - { - g2.setFont(comp.getFont()); - visitor.visit(comp, g2); - } - finally - { - g2.dispose(); - } - } - - /** - * Overridden to dispatch events to lightweight descendents. - * - * @param e the event to dispatch. - */ - void dispatchEventImpl(AWTEvent e) - { - LightweightDispatcher dispatcher = LightweightDispatcher.getInstance(); - if (! isLightweight() && dispatcher.dispatchEvent(e)) - { - // Some lightweight descendent got this event dispatched. Consume - // it and let the peer handle it. - e.consume(); - ComponentPeer p = peer; - if (p != null) - p.handleEvent(e); - } - else - { - super.dispatchEventImpl(e); - } - } - - /** - * This is called by the lightweight dispatcher to avoid recursivly - * calling into the lightweight dispatcher. - * - * @param e the event to dispatch - * - * @see LightweightDispatcher#redispatch(MouseEvent, Component, int) - */ - void dispatchNoLightweight(AWTEvent e) - { - super.dispatchEventImpl(e); - } - - /** - * Tests if this container has an interest in the given event id. - * - * @param eventId The event id to check. - * - * @return <code>true</code> if a listener for the event id exists or - * if the eventMask is set for the event id. - * - * @see java.awt.Component#eventTypeEnabled(int) - */ - boolean eventTypeEnabled(int eventId) - { - if(eventId <= ContainerEvent.CONTAINER_LAST - && eventId >= ContainerEvent.CONTAINER_FIRST) - return containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0; - else - return super.eventTypeEnabled(eventId); - } - - // This is used to implement Component.transferFocus. - Component findNextFocusComponent(Component child) - { - synchronized (getTreeLock ()) - { - int start, end; - if (child != null) - { - for (start = 0; start < ncomponents; ++start) - { - if (component[start] == child) - break; - } - end = start; - // This special case lets us be sure to terminate. - if (end == 0) - end = ncomponents; - ++start; - } - else - { - start = 0; - end = ncomponents; - } - - for (int j = start; j != end; ++j) - { - if (j >= ncomponents) - { - // The JCL says that we should wrap here. However, that - // seems wrong. To me it seems that focus order should be - // global within in given window. So instead if we reach - // the end we try to look in our parent, if we have one. - if (parent != null) - return parent.findNextFocusComponent(this); - j -= ncomponents; - } - if (component[j] instanceof Container) - { - Component c = component[j]; - c = c.findNextFocusComponent(null); - if (c != null) - return c; - } - else if (component[j].isFocusTraversable()) - return component[j]; - } - - return null; - } - } - - /** - * Fires hierarchy events to the children of this container and this - * container itself. This overrides {@link Component#fireHierarchyEvent} - * in order to forward this event to all children. - */ - void fireHierarchyEvent(int id, Component changed, Container parent, - long flags) - { - // Only propagate event if there is actually a listener waiting for it. - if ((id == HierarchyEvent.HIERARCHY_CHANGED && numHierarchyListeners > 0) - || ((id == HierarchyEvent.ANCESTOR_MOVED - || id == HierarchyEvent.ANCESTOR_RESIZED) - && numHierarchyBoundsListeners > 0)) - { - for (int i = 0; i < ncomponents; i++) - component[i].fireHierarchyEvent(id, changed, parent, flags); - super.fireHierarchyEvent(id, changed, parent, flags); - } - } - - /** - * Adjusts the number of hierarchy listeners of this container and all of - * its parents. This is called by the add/remove listener methods and - * structure changing methods in Container. - * - * @param type the type, either {@link AWTEvent#HIERARCHY_BOUNDS_EVENT_MASK} - * or {@link AWTEvent#HIERARCHY_EVENT_MASK} - * @param delta the number of listeners added or removed - */ - void updateHierarchyListenerCount(long type, int delta) - { - if (type == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) - numHierarchyBoundsListeners += delta; - else if (type == AWTEvent.HIERARCHY_EVENT_MASK) - numHierarchyListeners += delta; - else - assert false : "Should not reach here"; - - if (parent != null) - parent.updateHierarchyListenerCount(type, delta); - } - - /** - * Notifies interested listeners about resizing or moving the container. - * This performs the super behaviour (sending component events) and - * additionally notifies any hierarchy bounds listeners on child components. - * - * @param resized true if the component has been resized, false otherwise - * @param moved true if the component has been moved, false otherwise - */ - void notifyReshape(boolean resized, boolean moved) - { - // Notify component listeners. - super.notifyReshape(resized, moved); - - if (ncomponents > 0) - { - // Notify hierarchy bounds listeners. - if (resized) - { - for (int i = 0; i < getComponentCount(); i++) - { - Component child = getComponent(i); - child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_RESIZED, - this, parent, 0); - } - } - if (moved) - { - for (int i = 0; i < getComponentCount(); i++) - { - Component child = getComponent(i); - child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_MOVED, - this, parent, 0); - } - } - } - } - - private void addNotifyContainerChildren() - { - synchronized (getTreeLock ()) - { - for (int i = ncomponents; --i >= 0; ) - { - component[i].addNotify(); - } - } - } - - /** - * Deserialize this Container: - * <ol> - * <li>Read from the stream the default serializable fields.</li> - * <li>Read a list of serializable ContainerListeners as optional - * data. If the list is null, no listeners will be registered.</li> - * <li>Read this Container's FocusTraversalPolicy as optional data. - * If this is null, then this Container will use a - * DefaultFocusTraversalPolicy.</li> - * </ol> - * - * @param s the stream to read from - * @throws ClassNotFoundException if deserialization fails - * @throws IOException if the stream fails - */ - private void readObject (ObjectInputStream s) - throws ClassNotFoundException, IOException - { - s.defaultReadObject (); - String key = (String) s.readObject (); - while (key != null) - { - Object object = s.readObject (); - if ("containerL".equals (key)) - addContainerListener((ContainerListener) object); - // FIXME: under what key is the focus traversal policy stored? - else if ("focusTraversalPolicy".equals (key)) - setFocusTraversalPolicy ((FocusTraversalPolicy) object); - - key = (String) s.readObject(); - } - } - - /** - * Serialize this Container: - * <ol> - * <li>Write to the stream the default serializable fields.</li> - * <li>Write the list of serializable ContainerListeners as optional - * data.</li> - * <li>Write this Container's FocusTraversalPolicy as optional data.</li> - * </ol> - * - * @param s the stream to write to - * @throws IOException if the stream fails - */ - private void writeObject (ObjectOutputStream s) throws IOException - { - s.defaultWriteObject (); - AWTEventMulticaster.save (s, "containerL", containerListener); - if (focusTraversalPolicy instanceof Serializable) - s.writeObject (focusTraversalPolicy); - else - s.writeObject (null); - } - - // Nested classes. - - /* The following classes are used in concert with the - visitChildren() method to implement all the graphics operations - that requires traversal of the containment hierarchy. */ - - abstract static class GfxVisitor - { - public abstract void visit(Component c, Graphics gfx); - } - - static class GfxPaintVisitor extends GfxVisitor - { - public static final GfxVisitor INSTANCE = new GfxPaintVisitor(); - - public void visit(Component c, Graphics gfx) - { - c.paint(gfx); - } - } - - static class GfxPrintVisitor extends GfxVisitor - { - public static final GfxVisitor INSTANCE = new GfxPrintVisitor(); - - public void visit(Component c, Graphics gfx) - { - c.print(gfx); - } - } - - static class GfxPaintAllVisitor extends GfxVisitor - { - public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor(); - - public void visit(Component c, Graphics gfx) - { - c.paintAll(gfx); - } - } - - static class GfxPrintAllVisitor extends GfxVisitor - { - public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor(); - - public void visit(Component c, Graphics gfx) - { - c.printAll(gfx); - } - } - - /** - * This class provides accessibility support for subclasses of container. - * - * @author Eric Blake (ebb9@email.byu.edu) - * - * @since 1.3 - */ - protected class AccessibleAWTContainer extends AccessibleAWTComponent - { - /** - * Compatible with JDK 1.4+. - */ - private static final long serialVersionUID = 5081320404842566097L; - - /** - * The handler to fire PropertyChange when children are added or removed. - * - * @serial the handler for property changes - */ - protected ContainerListener accessibleContainerHandler - = new AccessibleContainerHandler(); - - /** - * The default constructor. - */ - protected AccessibleAWTContainer() - { - Container.this.addContainerListener(accessibleContainerHandler); - } - - /** - * Return the number of accessible children of the containing accessible - * object (at most the total number of its children). - * - * @return the number of accessible children - */ - public int getAccessibleChildrenCount() - { - synchronized (getTreeLock ()) - { - int count = 0; - int i = component == null ? 0 : component.length; - while (--i >= 0) - if (component[i] instanceof Accessible) - count++; - return count; - } - } - - /** - * Return the nth accessible child of the containing accessible object. - * - * @param i the child to grab, zero-based - * @return the accessible child, or null - */ - public Accessible getAccessibleChild(int i) - { - synchronized (getTreeLock ()) - { - if (component == null) - return null; - int index = -1; - while (i >= 0 && ++index < component.length) - if (component[index] instanceof Accessible) - i--; - if (i < 0) - return (Accessible) component[index]; - return null; - } - } - - /** - * Return the accessible child located at point (in the parent's - * coordinates), if one exists. - * - * @param p the point to look at - * - * @return an accessible object at that point, or null - * - * @throws NullPointerException if p is null - */ - public Accessible getAccessibleAt(Point p) - { - Component c = getComponentAt(p.x, p.y); - return c != Container.this && c instanceof Accessible ? (Accessible) c - : null; - } - - /** - * This class fires a <code>PropertyChange</code> listener, if registered, - * when children are added or removed from the enclosing accessible object. - * - * @author Eric Blake (ebb9@email.byu.edu) - * - * @since 1.3 - */ - protected class AccessibleContainerHandler implements ContainerListener - { - /** - * Default constructor. - */ - protected AccessibleContainerHandler() - { - // Nothing to do here. - } - - /** - * Fired when a component is added; forwards to the PropertyChange - * listener. - * - * @param e the container event for adding - */ - public void componentAdded(ContainerEvent e) - { - AccessibleAWTContainer.this.firePropertyChange - (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild()); - } - - /** - * Fired when a component is removed; forwards to the PropertyChange - * listener. - * - * @param e the container event for removing - */ - public void componentRemoved(ContainerEvent e) - { - AccessibleAWTContainer.this.firePropertyChange - (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null); - } - } // class AccessibleContainerHandler - } // class AccessibleAWTContainer -} // class Container |