package java.awt;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.peer.ContainerPeer;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
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;
import javax.swing.SwingUtilities;
public class Container extends Component
{
private static final long serialVersionUID = 4613797578919906343L;
int ncomponents;
Component[] component;
LayoutManager layoutMgr;
LightweightDispatcher dispatcher;
Dimension maxSize;
boolean focusCycleRoot;
int containerSerializedDataVersion;
transient ContainerListener containerListener;
transient PropertyChangeSupport changeSupport;
private FocusTraversalPolicy focusTraversalPolicy;
transient Set[] focusTraversalKeys;
public Container()
{
}
public int getComponentCount()
{
return countComponents ();
}
public int countComponents()
{
return ncomponents;
}
public Component getComponent(int n)
{
synchronized (getTreeLock ())
{
if (n < 0 || n >= ncomponents)
throw new ArrayIndexOutOfBoundsException("no such component");
return component[n];
}
}
public Component[] getComponents()
{
synchronized (getTreeLock ())
{
Component[] result = new Component[ncomponents];
if (ncomponents > 0)
System.arraycopy(component, 0, result, 0, ncomponents);
return result;
}
}
protected void swapComponents (int i, int j)
{
synchronized (getTreeLock ())
{
if (i < 0
|| i >= component.length
|| j < 0
|| j >= component.length)
throw new ArrayIndexOutOfBoundsException ();
Component tmp = component[i];
component[i] = component[j];
component[j] = tmp;
}
}
public Insets getInsets()
{
return insets ();
}
public Insets insets()
{
if (peer == null)
return new Insets (0, 0, 0, 0);
return ((ContainerPeer) peer).getInsets ();
}
public Component add(Component comp)
{
addImpl(comp, null, -1);
return comp;
}
public Component add(String name, Component comp)
{
addImpl(comp, name, -1);
return comp;
}
public Component add(Component comp, int index)
{
addImpl(comp, null, index);
return comp;
}
public void add(Component comp, Object constraints)
{
addImpl(comp, constraints, -1);
}
public void add(Component comp, Object constraints, int index)
{
addImpl(comp, constraints, index);
}
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();
if (comp.parent != null)
comp.parent.remove(comp);
comp.parent = this;
if (peer != null)
{
if (comp.isLightweight ())
{
enableEvents (comp.eventMask);
if (!isLightweight ())
enableEvents (AWTEvent.PAINT_EVENT_MASK);
}
}
invalidate();
if (component == null)
component = new Component[4];
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;
}
if (layoutMgr != null)
{
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(null, comp);
}
if (isShowing ())
{
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_ADDED,
comp);
getToolkit().getSystemEventQueue().postEvent(ce);
}
}
}
public void remove(int index)
{
synchronized (getTreeLock ())
{
Component r = component[index];
r.removeNotify();
System.arraycopy(component, index + 1, component, index,
ncomponents - index - 1);
component[--ncomponents] = null;
invalidate();
if (layoutMgr != null)
layoutMgr.removeLayoutComponent(r);
r.parent = null;
if (isShowing ())
{
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED,
r);
getToolkit().getSystemEventQueue().postEvent(ce);
}
}
}
public void remove(Component comp)
{
synchronized (getTreeLock ())
{
for (int i = 0; i < ncomponents; ++i)
{
if (component[i] == comp)
{
remove(i);
break;
}
}
}
}
public void removeAll()
{
synchronized (getTreeLock ())
{
while (ncomponents > 0)
remove(0);
}
}
public LayoutManager getLayout()
{
return layoutMgr;
}
public void setLayout(LayoutManager mgr)
{
layoutMgr = mgr;
invalidate();
}
public void doLayout()
{
layout ();
}
public void layout()
{
if (layoutMgr != null)
layoutMgr.layoutContainer (this);
}
public void invalidate()
{
super.invalidate();
}
public void validate()
{
synchronized (getTreeLock ())
{
if (! isValid() && peer != null)
{
validateTree();
}
}
}
void invalidateTree()
{
for (int i = 0; i < ncomponents; i++)
{
Component comp = component[i];
comp.invalidate();
if (comp instanceof Container)
((Container) comp).invalidateTree();
}
}
protected void validateTree()
{
if (valid)
return;
ContainerPeer cPeer = null;
if (peer != null && ! (peer instanceof LightweightPeer))
{
cPeer = (ContainerPeer) peer;
cPeer.beginValidate();
}
for (int i = 0; i < ncomponents; ++i)
{
Component comp = component[i];
if (comp.getPeer () == null)
comp.addNotify();
}
doLayout ();
for (int i = 0; i < ncomponents; ++i)
{
Component comp = component[i];
if (! comp.isValid())
{
if (comp instanceof Container)
{
((Container) comp).validateTree();
}
else
{
component[i].validate();
}
}
}
valid = true;
if (cPeer != null)
cPeer.endValidate();
}
public void setFont(Font f)
{
super.setFont(f);
invalidateTree();
}
public Dimension getPreferredSize()
{
return preferredSize ();
}
public Dimension preferredSize()
{
if (layoutMgr != null)
return layoutMgr.preferredLayoutSize (this);
else
return super.preferredSize ();
}
public Dimension getMinimumSize()
{
return minimumSize ();
}
public Dimension minimumSize()
{
if (layoutMgr != null)
return layoutMgr.minimumLayoutSize (this);
else
return super.minimumSize ();
}
public Dimension getMaximumSize()
{
if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
{
LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
return lm2.maximumLayoutSize(this);
}
else
return super.getMaximumSize();
}
public float getAlignmentX()
{
if (layoutMgr instanceof LayoutManager2)
{
LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
return lm2.getLayoutAlignmentX(this);
}
else
return super.getAlignmentX();
}
public float getAlignmentY()
{
if (layoutMgr instanceof LayoutManager2)
{
LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
return lm2.getLayoutAlignmentY(this);
}
else
return super.getAlignmentY();
}
public void paint(Graphics g)
{
if (!isShowing())
return;
super.paint(g);
visitChildren(g, GfxPaintVisitor.INSTANCE, false);
}
public void update(Graphics g)
{
super.update(g);
}
public void print(Graphics g)
{
super.print(g);
visitChildren(g, GfxPrintVisitor.INSTANCE, true);
}
public void paintComponents(Graphics g)
{
super.paint(g);
visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
}
public void printComponents(Graphics g)
{
super.paint(g);
visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
}
public synchronized void addContainerListener(ContainerListener listener)
{
containerListener = AWTEventMulticaster.add(containerListener, listener);
}
public synchronized void removeContainerListener(ContainerListener listener)
{
containerListener = AWTEventMulticaster.remove(containerListener, listener);
}
public synchronized ContainerListener[] getContainerListeners()
{
return (ContainerListener[])
AWTEventMulticaster.getListeners(containerListener,
ContainerListener.class);
}
public EventListener[] getListeners(Class listenerType)
{
if (listenerType == ContainerListener.class)
return getContainerListeners();
return super.getListeners(listenerType);
}
protected void processEvent(AWTEvent e)
{
if (e instanceof ContainerEvent)
processContainerEvent((ContainerEvent) e);
else
super.processEvent(e);
}
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;
}
}
public void deliverEvent(Event e)
{
if (!handleEvent (e))
{
synchronized (getTreeLock ())
{
Component parent = getParent ();
if (parent != null)
parent.deliverEvent (e);
}
}
}
public Component getComponentAt(int x, int y)
{
return locate (x, y);
}
public Component locate(int x, int y)
{
synchronized (getTreeLock ())
{
if (!contains (x, y))
return null;
for (int i = 0; i < ncomponents; ++i)
{
if (!component[i].isVisible ())
continue;
int x2 = x - component[i].x;
int y2 = y - component[i].y;
if (component[i].contains (x2, y2))
return component[i];
}
return this;
}
}
public Component getComponentAt(Point p)
{
return getComponentAt (p.x, p.y);
}
public Component findComponentAt(int x, int y)
{
synchronized (getTreeLock ())
{
if (! contains(x, y))
return null;
for (int i = 0; i < ncomponents; ++i)
{
if (!component[i].isVisible())
continue;
int x2 = x - component[i].x;
int y2 = y - component[i].y;
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;
}
}
public Component findComponentAt(Point p)
{
return findComponentAt(p.x, p.y);
}
public void addNotify()
{
super.addNotify();
addNotifyContainerChildren();
}
public void removeNotify()
{
synchronized (getTreeLock ())
{
for (int i = 0; i < ncomponents; ++i)
component[i].removeNotify();
super.removeNotify();
}
}
public boolean isAncestorOf(Component comp)
{
synchronized (getTreeLock ())
{
while (true)
{
if (comp == null)
return false;
if (comp == this)
return true;
comp = comp.getParent();
}
}
}
protected String paramString()
{
if (layoutMgr == null)
return super.paramString();
StringBuffer sb = new StringBuffer();
sb.append(super.paramString());
sb.append(",layout=");
sb.append(layoutMgr.getClass().getName());
return sb.toString();
}
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);
}
}
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);
}
}
public void setFocusTraversalKeys(int id, Set 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[3];
keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
firePropertyChange (name, focusTraversalKeys[id], keystrokes);
focusTraversalKeys[id] = keystrokes;
}
public Set 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;
}
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;
}
public boolean isFocusCycleRoot (Container c)
{
if (this == c
&& isFocusCycleRoot ())
return true;
Container ancestor = getFocusCycleRootAncestor ();
if (c == ancestor)
return true;
return false;
}
public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
{
focusTraversalPolicy = policy;
}
public FocusTraversalPolicy getFocusTraversalPolicy ()
{
if (!isFocusCycleRoot ())
return null;
if (focusTraversalPolicy == null)
{
Container ancestor = getFocusCycleRootAncestor ();
if (ancestor != this)
return ancestor.getFocusTraversalPolicy ();
else
{
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
return manager.getDefaultFocusTraversalPolicy ();
}
}
else
return focusTraversalPolicy;
}
public boolean isFocusTraversalPolicySet ()
{
return focusTraversalPolicy == null;
}
public void setFocusCycleRoot (boolean focusCycleRoot)
{
this.focusCycleRoot = focusCycleRoot;
}
public boolean isFocusCycleRoot ()
{
return focusCycleRoot;
}
public void transferFocusDownCycle ()
{
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
manager.downFocusCycle (this);
}
public void applyComponentOrientation (ComponentOrientation orientation)
{
if (orientation == null)
throw new NullPointerException ();
}
public void addPropertyChangeListener (PropertyChangeListener listener)
{
if (listener == null)
return;
if (changeSupport == null)
changeSupport = new PropertyChangeSupport (this);
changeSupport.addPropertyChangeListener (listener);
}
public void addPropertyChangeListener (String name,
PropertyChangeListener listener)
{
if (listener == null)
return;
if (changeSupport == null)
changeSupport = new PropertyChangeSupport (this);
changeSupport.addPropertyChangeListener (name, listener);
}
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 && ! (comp instanceof Container));
if (applicable)
visitChild(gfx, visitor, comp);
}
}
}
private void visitChild(Graphics gfx, GfxVisitor visitor,
Component comp)
{
Rectangle bounds = comp.getBounds();
Rectangle oldClip = gfx.getClipBounds();
if (oldClip == null)
oldClip = bounds;
Rectangle clip = oldClip.intersection(bounds);
if (clip.isEmpty()) return;
boolean clipped = false;
boolean translated = false;
try
{
gfx.setClip(clip.x, clip.y, clip.width, clip.height);
clipped = true;
gfx.translate(bounds.x, bounds.y);
translated = true;
visitor.visit(comp, gfx);
}
finally
{
if (translated)
gfx.translate (-bounds.x, -bounds.y);
if (clipped)
gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
}
}
void dispatchEventImpl(AWTEvent e)
{
if (eventTypeEnabled (e.id)
&& dispatcher != null
&& dispatcher.handleEvent (e))
return;
if ((e.id <= ContainerEvent.CONTAINER_LAST
&& e.id >= ContainerEvent.CONTAINER_FIRST)
&& (containerListener != null
|| (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
processEvent(e);
else
super.dispatchEventImpl(e);
}
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;
if (end == 0)
end = ncomponents;
++start;
}
else
{
start = 0;
end = ncomponents;
}
for (int j = start; j != end; ++j)
{
if (j >= ncomponents)
{
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;
}
}
private void addNotifyContainerChildren()
{
synchronized (getTreeLock ())
{
for (int i = ncomponents; --i >= 0; )
{
component[i].addNotify();
if (component[i].isLightweight ())
{
if (! this.isLightweight())
{
if (dispatcher == null)
dispatcher = new LightweightDispatcher (this);
}
enableEvents(component[i].eventMask);
if (peer != null && !isLightweight ())
enableEvents (AWTEvent.PAINT_EVENT_MASK);
}
}
}
}
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);
else if ("focusTraversalPolicy".equals (key))
setFocusTraversalPolicy ((FocusTraversalPolicy) object);
key = (String) s.readObject();
}
}
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);
}
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);
}
}
protected class AccessibleAWTContainer extends AccessibleAWTComponent
{
private static final long serialVersionUID = 5081320404842566097L;
protected ContainerListener accessibleContainerHandler
= new AccessibleContainerHandler();
protected AccessibleAWTContainer()
{
Container.this.addContainerListener(accessibleContainerHandler);
}
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;
}
}
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;
}
}
public Accessible getAccessibleAt(Point p)
{
Component c = getComponentAt(p.x, p.y);
return c != Container.this && c instanceof Accessible ? (Accessible) c
: null;
}
protected class AccessibleContainerHandler implements ContainerListener
{
protected AccessibleContainerHandler()
{
}
public void componentAdded(ContainerEvent e)
{
AccessibleAWTContainer.this.firePropertyChange
(ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
}
public void componentRemoved(ContainerEvent e)
{
AccessibleAWTContainer.this.firePropertyChange
(ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
}
} } }
class LightweightDispatcher implements Serializable
{
private static final long serialVersionUID = 5184291520170872969L;
private Container nativeContainer;
private Cursor nativeCursor;
private long eventMask;
private transient Component mouseEventTarget;
private transient Component pressedComponent;
private transient Component lastComponentEntered;
private transient int pressCount;
LightweightDispatcher(Container c)
{
nativeContainer = c;
}
void acquireComponentForMouseEvent(MouseEvent me)
{
int x = me.getX ();
int y = me.getY ();
Component parent = nativeContainer;
Component candidate = null;
Point p = me.getPoint();
while (candidate == null && parent != null)
{
candidate =
SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
if (candidate == null || (candidate.eventMask & me.getID()) == 0)
{
candidate = null;
p = SwingUtilities.convertPoint(parent, p.x, p.y, parent.parent);
parent = parent.parent;
}
}
if (candidate == nativeContainer)
candidate = null;
if (lastComponentEntered != null
&& lastComponentEntered.isShowing()
&& lastComponentEntered != candidate)
{
if (SwingUtilities.isDescendingFrom(lastComponentEntered, nativeContainer))
{
Point tp =
SwingUtilities.convertPoint(nativeContainer,
x, y, lastComponentEntered);
MouseEvent exited = new MouseEvent (lastComponentEntered,
MouseEvent.MOUSE_EXITED,
me.getWhen (),
me.getModifiersEx (),
tp.x, tp.y,
me.getClickCount (),
me.isPopupTrigger (),
me.getButton ());
lastComponentEntered.dispatchEvent (exited);
}
lastComponentEntered = null;
}
if (candidate != null)
{
mouseEventTarget = candidate;
if (candidate.isLightweight()
&& candidate.isShowing()
&& candidate != nativeContainer
&& candidate != lastComponentEntered)
{
lastComponentEntered = mouseEventTarget;
Point cp = SwingUtilities.convertPoint(nativeContainer,
x, y, lastComponentEntered);
MouseEvent entered = new MouseEvent (lastComponentEntered,
MouseEvent.MOUSE_ENTERED,
me.getWhen (),
me.getModifiersEx (),
cp.x, cp.y,
me.getClickCount (),
me.isPopupTrigger (),
me.getButton ());
lastComponentEntered.dispatchEvent (entered);
}
}
if (me.getID() == MouseEvent.MOUSE_RELEASED
|| me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
|| me.getID() == MouseEvent.MOUSE_DRAGGED)
if (SwingUtilities.isDescendingFrom(pressedComponent, nativeContainer))
mouseEventTarget = pressedComponent;
else if (me.getID() == MouseEvent.MOUSE_CLICKED)
{
if (candidate != pressedComponent)
mouseEventTarget = null;
else if (pressCount == 0)
pressedComponent = null;
}
}
boolean handleEvent(AWTEvent e)
{
if (e instanceof MouseEvent)
{
MouseEvent me = (MouseEvent) e;
acquireComponentForMouseEvent(me);
if (mouseEventTarget != null
&& mouseEventTarget.isShowing()
&& e.getID() != MouseEvent.MOUSE_ENTERED
&& e.getID() != MouseEvent.MOUSE_EXITED)
{
MouseEvent newEvt =
SwingUtilities.convertMouseEvent(nativeContainer, me,
mouseEventTarget);
mouseEventTarget.dispatchEvent(newEvt);
switch (e.getID())
{
case MouseEvent.MOUSE_PRESSED:
if (pressCount++ == 0)
pressedComponent = mouseEventTarget;
break;
case MouseEvent.MOUSE_RELEASED:
if (--pressCount == 0
&& mouseEventTarget != pressedComponent)
pressedComponent = null;
break;
}
if (newEvt.isConsumed())
e.consume();
}
}
return e.isConsumed();
}
}