📄 container.java
字号:
/** * Container - abstract base for all Components capable of having children * * Copyright (c) 1998 * Transvirtual Technologies, Inc. All rights reserved. * Copyright (c) 2006 * Kaffe.org developers. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution * of this file. * * original code P.C.Mehlitz * some code taken or adapted from Classpath */package java.awt;import java.awt.event.ContainerEvent;import java.awt.event.ContainerListener;import java.awt.event.KeyEvent;import java.awt.event.PaintEvent;import java.io.PrintStream;import java.io.PrintWriter;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.Set;abstract 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; /* 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; // ContainerListener cntrListener; Insets insets = Insets.noInsets;protected Container () {} /** * 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 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); } /** * 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; }public void addContainerListener ( ContainerListener newListener ) { containerListener = AWTEventMulticaster.add( containerListener, newListener);} /** * @since 1.4 */ public synchronized ContainerListener[] getContainerListeners() { return (ContainerListener[]) AWTEventMulticaster.getListeners(containerListener, ContainerListener.class); }protected void addImpl(Component child, Object constraints, int index ) { synchronized ( treeLock ) { if (index < -1 || index > ncomponents) { throw new IllegalArgumentException("bad index: " + index); } // This test isn't done because we actually need this functionality // for the native windowing system //else if (child instanceof Window) { // throw new IllegalArgumentException("component is Window"); //} else if (child instanceof Container && this.parent == child) { throw new IllegalArgumentException("child is a bad container"); } if ( child.parent != null ) { child.parent.remove(child); } if ( component == null ) { component= new Component[3]; } else if ( ncomponents == component.length ) { Component[] old = component; component = new Component[ ncomponents * 2]; System.arraycopy( old, 0, component, 0, ncomponents); } if (index < 0 || ncomponents == 0 || index == ncomponents) { // append component[ncomponents] = child; } else if (index < ncomponents) { // insert at index System.arraycopy( component, index, component, index+1, ncomponents - index); component[index] = child; } ncomponents++; child.parent = this; if ( (flags & IS_VALID) != 0 ) invalidate(); // if we are already addNotified (this is a subsequent add), // we immediately have to addNotify the child, too if ( (flags & IS_ADD_NOTIFIED) != 0 ) { child.addNotify(); // This isn't required in case we are subsequently validated (what is the // correct thing to do), but native widgets would cause a repaint regardless // of that. Comment this out if you believe in correct apps if ( (child.flags & IS_NATIVE_LIKE) != 0 ) child.repaint(); } // inherit parent attributes (if not overriden by child) if ( (flags & (IS_PARENT_SHOWING | IS_VISIBLE)) == (IS_PARENT_SHOWING | IS_VISIBLE) ){ child.flags |= IS_PARENT_SHOWING; child.propagateParentShowing( false); } if ( (child.flags & IS_BG_COLORED) == 0 ) child.propagateBgClr( background); if ( (child.flags & IS_FG_COLORED) == 0 ) child.propagateFgClr( foreground); if ( (child.flags & IS_FONTIFIED) == 0 ) child.propagateFont( font); // Some LayoutManagers track adding/removing components. Since this seems to be // done after a potential addNotify, inform them here // (wouldn't it be nice to have a single LayoutManager interface?) if ( layoutMgr != null ) { if ( layoutMgr instanceof LayoutManager2 ) { ((LayoutManager2)layoutMgr).addLayoutComponent( child, constraints); } if (constraints instanceof String) { layoutMgr.addLayoutComponent( (String)constraints, child); } } if ( (containerListener != null) || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ){ AWTEvent.sendEvent( ContainerEvt.getEvent( this, ContainerEvent.COMPONENT_ADDED, child), false); } }}public void addNotify() { super.addNotify(); for ( int i=0; i<ncomponents; i++ ) { component[i].addNotify(); }}Graphics clipSiblings ( Component child, NativeGraphics g ) { int i, xClip, yClip, xwClip, yhClip, cxw, cyh; Component c; xClip = g.xClip + g.xOffset; yClip = g.yClip + g.yOffset; xwClip = xClip + g.wClip; yhClip = yClip + g.hClip; for ( i=ncomponents-1; (i >= 0) && (component[i] != child) ; i-- ); for ( i--; i >= 0; i-- ) { c = component[i]; cxw = c.x + c.width; cyh = c.y + c.height; if ( (c.x > xwClip) || (c.y > yhClip) || (cxw < xClip) || (cyh < yClip) ) continue; // not yet implemented } return g;}/** * @deprecated, use getComponentCount() */public int countComponents() { return ncomponents;}public void doLayout() { layout();}void dump ( String prefix ) { String prfx = prefix + " "; super.dump( prefix); for ( int i=0; i<ncomponents; i++ ) { component[i].dump( prfx + i + " "); }}void emitRepaints ( int ux, int uy, int uw, int uh ) { // This looks too similiar to NativeGraphics.paintChild(), but we can't // move that one (because of clip bounds access). On the other hand, we // don't want to give up precise clipping, here (flicker). // It also does a lot of redundant computation compared to markRepaints, and // that is why it should be called after checking "hasDirties()". It's a petty // we have to go through all of this because of embedded, app-specific IS_NATIVE_LIKE // components (Panels, Canvases), which get their repaints by the native windowing system // (and that is NOT specified!!) int uxw = ux + uw; int uyh = uy + uh; for ( int i=0; i<ncomponents; i++ ) { Component c = component[i]; if ( (c.flags & IS_VISIBLE) != 0 ) { int cxw = c.x + c.width; int cyh = c.y + c.height; int uxx = (ux < c.x ) ? 0 : ux - c.x; int uyy = (uy < c.y ) ? 0 : uy - c.y; int uww = (uxw < cxw) ? (uxw - c.x - uxx) : c.width; int uhh = (uyh < cyh) ? (uyh - c.y - uyy) : c.height; if ( (c.flags & IS_DIRTY) != 0 ) { // Oh what a joy - Panels & Canvases don't get update() called in respond to // window manager initiated draw requests (resize). Of course, this is different // for explicit repaint() calls, which triggers update(). This is likely to be a bug // (in the CanvasPeer), but again we have to be compatible (for a while). // Also shows up in NativeGraphics.paintChild() Toolkit.eventQueue.postPaintEvent( ((c.flags & IS_ASYNC_UPDATED) != 0 ? PaintEvent.PAINT : PaintEvent.UPDATE), c, uxx, uyy, uww, uhh); } if ( c instanceof Container ) ((Container)c).emitRepaints( uxx, uyy, uww, uhh); } }}public float getAlignmentX () { if ( layoutMgr instanceof LayoutManager2 ) { return ((LayoutManager2)layoutMgr).getLayoutAlignmentX( this); } else { return super.getAlignmentX(); }}public float getAlignmentY () { if ( layoutMgr instanceof LayoutManager2 ) { return ((LayoutManager2)layoutMgr).getLayoutAlignmentY( this); } else { return super.getAlignmentY(); }}public Component getComponent ( int index ) { return component[index];} /** * 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. * @since 1.2 */ 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. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -