Commit 459c4c51 by Tom Tromey Committed by Tom Tromey

Container.java (validate): Use tree lock.

	* java/awt/Container.java (validate): Use tree lock.
	(getComponent): Likewise.
	(getComponents): Likewise.
	(addImpl): Likewise.
	(remove): Likewise.
	(removeAll): Likewise.
	(processEvent): Fixed indentation.
	(getComponentAt): Use tree lock.
	(findComponentAt): Likewise.
	(removeNotify): Likewise.
	(isAncestorOf): Likewise.
	(list): Likewise.
	(visitChildren): Likewise.
	(findNextFocusComponent): Likewise.
	(addNotifyContainerChildren): Likewise.
	(getAccessibleChildrenCount): Likewise.
	(getAccessibleChild): Likewise.

From-SVN: r59009
parent f981a754
2002-11-10 Tom Tromey <tromey@redhat.com> 2002-11-10 Tom Tromey <tromey@redhat.com>
* java/awt/Container.java (validate): Use tree lock.
(getComponent): Likewise.
(getComponents): Likewise.
(addImpl): Likewise.
(remove): Likewise.
(removeAll): Likewise.
(processEvent): Fixed indentation.
(getComponentAt): Use tree lock.
(findComponentAt): Likewise.
(removeNotify): Likewise.
(isAncestorOf): Likewise.
(list): Likewise.
(visitChildren): Likewise.
(findNextFocusComponent): Likewise.
(addNotifyContainerChildren): Likewise.
(getAccessibleChildrenCount): Likewise.
(getAccessibleChild): Likewise.
* java/awt/GridLayout.java (layoutContainer): Use tree lock. * java/awt/GridLayout.java (layoutContainer): Use tree lock.
(getSize): Likewise. (getSize): Likewise.
* java/awt/FlowLayout.java (layoutContainer): Use tree lock. * java/awt/FlowLayout.java (layoutContainer): Use tree lock.
......
...@@ -123,9 +123,12 @@ public class Container extends Component ...@@ -123,9 +123,12 @@ public class Container extends Component
*/ */
public Component getComponent(int n) public Component getComponent(int n)
{ {
if (n < 0 || n >= ncomponents) synchronized (getTreeLock ())
throw new ArrayIndexOutOfBoundsException("no such component"); {
return component[n]; if (n < 0 || n >= ncomponents)
throw new ArrayIndexOutOfBoundsException("no such component");
return component[n];
}
} }
/** /**
...@@ -135,10 +138,13 @@ public class Container extends Component ...@@ -135,10 +138,13 @@ public class Container extends Component
*/ */
public Component[] getComponents() public Component[] getComponents()
{ {
Component[] result = new Component[ncomponents]; synchronized (getTreeLock ())
if (ncomponents > 0) {
System.arraycopy(component, 0, result, 0, ncomponents); Component[] result = new Component[ncomponents];
return result; if (ncomponents > 0)
System.arraycopy(component, 0, result, 0, ncomponents);
return result;
}
} }
/** /**
...@@ -260,69 +266,72 @@ public class Container extends Component ...@@ -260,69 +266,72 @@ public class Container extends Component
*/ */
protected void addImpl(Component comp, Object constraints, int index) protected void addImpl(Component comp, Object constraints, int index)
{ {
if (index > ncomponents synchronized (getTreeLock ())
|| (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);
comp.parent = this;
if (peer != null)
{
comp.addNotify();
if (comp.isLightweight())
enableEvents(comp.eventMask);
}
invalidate();
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;
}
// Notify the layout manager.
if (layoutMgr != null)
{ {
if (layoutMgr instanceof LayoutManager2) if (index > ncomponents
{ || (index < 0 && index != -1)
LayoutManager2 lm2 = (LayoutManager2) layoutMgr; || comp instanceof Window
lm2.addLayoutComponent(comp, constraints); || (comp instanceof Container
} && ((Container) comp).isAncestorOf(this)))
else if (constraints instanceof String) throw new IllegalArgumentException();
layoutMgr.addLayoutComponent((String) constraints, comp);
else // Reparent component, and make sure component is instantiated if
layoutMgr.addLayoutComponent(null, comp); // we are.
if (comp.parent != null)
comp.parent.remove(comp);
comp.parent = this;
if (peer != null)
{
comp.addNotify();
if (comp.isLightweight())
enableEvents(comp.eventMask);
}
invalidate();
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;
}
// Notify the layout manager.
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);
}
// Post event to notify of adding the container.
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_ADDED,
comp);
getToolkit().getSystemEventQueue().postEvent(ce);
} }
// Post event to notify of adding the container.
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_ADDED,
comp);
getToolkit().getSystemEventQueue().postEvent(ce);
} }
/** /**
...@@ -332,24 +341,27 @@ public class Container extends Component ...@@ -332,24 +341,27 @@ public class Container extends Component
*/ */
public void remove(int index) public void remove(int index)
{ {
Component r = component[index]; synchronized (getTreeLock ())
{
Component r = component[index];
r.removeNotify(); r.removeNotify();
System.arraycopy(component, index + 1, component, index, System.arraycopy(component, index + 1, component, index,
ncomponents - index - 1); ncomponents - index - 1);
component[--ncomponents] = null; component[--ncomponents] = null;
invalidate(); invalidate();
if (layoutMgr != null) if (layoutMgr != null)
layoutMgr.removeLayoutComponent(r); layoutMgr.removeLayoutComponent(r);
// Post event to notify of adding the container. // Post event to notify of adding the container.
ContainerEvent ce = new ContainerEvent(this, ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED, ContainerEvent.COMPONENT_REMOVED,
r); r);
getToolkit().getSystemEventQueue().postEvent(ce); getToolkit().getSystemEventQueue().postEvent(ce);
}
} }
/** /**
...@@ -359,13 +371,16 @@ public class Container extends Component ...@@ -359,13 +371,16 @@ public class Container extends Component
*/ */
public void remove(Component comp) public void remove(Component comp)
{ {
for (int i = 0; i < ncomponents; ++i) synchronized (getTreeLock ())
{ {
if (component[i] == comp) for (int i = 0; i < ncomponents; ++i)
{ {
remove(i); if (component[i] == comp)
break; {
} remove(i);
break;
}
}
} }
} }
...@@ -374,8 +389,11 @@ public class Container extends Component ...@@ -374,8 +389,11 @@ public class Container extends Component
*/ */
public void removeAll() public void removeAll()
{ {
while (ncomponents > 0) synchronized (getTreeLock ())
remove(0); {
while (ncomponents > 0)
remove(0);
}
} }
/** /**
...@@ -433,8 +451,7 @@ public class Container extends Component ...@@ -433,8 +451,7 @@ public class Container extends Component
*/ */
public void validate() public void validate()
{ {
// FIXME: use the tree lock? synchronized (getTreeLock ())
synchronized (this)
{ {
if (! isValid()) if (! isValid())
{ {
...@@ -713,7 +730,8 @@ public class Container extends Component ...@@ -713,7 +730,8 @@ public class Container extends Component
{ {
if (e instanceof ContainerEvent) if (e instanceof ContainerEvent)
processContainerEvent((ContainerEvent) e); processContainerEvent((ContainerEvent) e);
else super.processEvent(e); else
super.processEvent(e);
} }
/** /**
...@@ -764,20 +782,23 @@ public class Container extends Component ...@@ -764,20 +782,23 @@ public class Container extends Component
*/ */
public Component getComponentAt(int x, int y) public Component getComponentAt(int x, int y)
{ {
if (! contains(x, y)) synchronized (getTreeLock ())
return null;
for (int i = 0; i < ncomponents; ++i)
{ {
// Ignore invisible children... if (! contains(x, y))
if (!component[i].isVisible()) return null;
continue; for (int i = 0; i < ncomponents; ++i)
{
int x2 = x - component[i].x; // Ignore invisible children...
int y2 = y - component[i].y; if (!component[i].isVisible())
if (component[i].contains(x2, y2)) continue;
return component[i];
int x2 = x - component[i].x;
int y2 = y - component[i].y;
if (component[i].contains(x2, y2))
return component[i];
}
return this;
} }
return this;
} }
/** /**
...@@ -818,31 +839,34 @@ public class Container extends Component ...@@ -818,31 +839,34 @@ public class Container extends Component
public Component findComponentAt(int x, int y) public Component findComponentAt(int x, int y)
{ {
if (! contains(x, y)) synchronized (getTreeLock ())
return null;
for (int i = 0; i < ncomponents; ++i)
{ {
// Ignore invisible children... if (! contains(x, y))
if (!component[i].isVisible()) return null;
continue;
for (int i = 0; i < ncomponents; ++i)
int x2 = x - component[i].x; {
int y2 = y - component[i].y; // Ignore invisible children...
// We don't do the contains() check right away because if (!component[i].isVisible())
// findComponentAt would redundantly do it first thing. continue;
if (component[i] instanceof Container)
{ int x2 = x - component[i].x;
Container k = (Container) component[i]; int y2 = y - component[i].y;
Component r = k.findComponentAt(x2, y2); // We don't do the contains() check right away because
if (r != null) // findComponentAt would redundantly do it first thing.
return r; if (component[i] instanceof Container)
} {
else if (component[i].contains(x2, y2)) Container k = (Container) component[i];
return 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;
} }
return this;
} }
public Component findComponentAt(Point p) public Component findComponentAt(Point p)
...@@ -868,9 +892,12 @@ public class Container extends Component ...@@ -868,9 +892,12 @@ public class Container extends Component
*/ */
public void removeNotify() public void removeNotify()
{ {
for (int i = 0; i < ncomponents; ++i) synchronized (getTreeLock ())
component[i].removeNotify(); {
super.removeNotify(); for (int i = 0; i < ncomponents; ++i)
component[i].removeNotify();
super.removeNotify();
}
} }
/** /**
...@@ -880,17 +907,20 @@ public class Container extends Component ...@@ -880,17 +907,20 @@ public class Container extends Component
* @param component The component to test. * @param component The component to test.
* *
* @return <code>true</code> if this container is an ancestor of the * @return <code>true</code> if this container is an ancestor of the
* specified component, <code>false</code>. * specified component, <code>false</code> otherwise.
*/ */
public boolean isAncestorOf(Component comp) public boolean isAncestorOf(Component comp)
{ {
while (true) synchronized (getTreeLock ())
{ {
if (comp == null) while (true)
return false; {
if (comp == this) if (comp == null)
return true; return false;
comp = comp.getParent(); if (comp == this)
return true;
comp = comp.getParent();
}
} }
} }
...@@ -918,9 +948,12 @@ public class Container extends Component ...@@ -918,9 +948,12 @@ public class Container extends Component
*/ */
public void list(PrintStream out, int indent) public void list(PrintStream out, int indent)
{ {
super.list(out, indent); synchronized (getTreeLock ())
for (int i = 0; i < ncomponents; ++i) {
component[i].list(out, indent + 2); super.list(out, indent);
for (int i = 0; i < ncomponents; ++i)
component[i].list(out, indent + 2);
}
} }
/** /**
...@@ -932,9 +965,12 @@ public class Container extends Component ...@@ -932,9 +965,12 @@ public class Container extends Component
*/ */
public void list(PrintWriter out, int indent) public void list(PrintWriter out, int indent)
{ {
super.list(out, indent); synchronized (getTreeLock ())
for (int i = 0; i < ncomponents; ++i) {
component[i].list(out, indent + 2); super.list(out, indent);
for (int i = 0; i < ncomponents; ++i)
component[i].list(out, indent + 2);
}
} }
public void setFocusTraversalKeys(int id, Set keys) public void setFocusTraversalKeys(int id, Set keys)
...@@ -1006,16 +1042,17 @@ public class Container extends Component ...@@ -1006,16 +1042,17 @@ public class Container extends Component
private void visitChildren(Graphics gfx, GfxVisitor visitor, private void visitChildren(Graphics gfx, GfxVisitor visitor,
boolean lightweightOnly) boolean lightweightOnly)
{ {
// FIXME: do locking synchronized (getTreeLock ())
for (int i = 0; i < ncomponents; ++i)
{ {
Component comp = component[i]; for (int i = 0; i < ncomponents; ++i)
boolean applicable = comp.isVisible() {
&& (comp.isLightweight() || !lightweightOnly); Component comp = component[i];
boolean applicable = comp.isVisible()
if (applicable) && (comp.isLightweight() || !lightweightOnly);
visitChild(gfx, visitor, comp);
if (applicable)
visitChild(gfx, visitor, comp);
}
} }
} }
...@@ -1061,59 +1098,65 @@ public class Container extends Component ...@@ -1061,59 +1098,65 @@ public class Container extends Component
// This is used to implement Component.transferFocus. // This is used to implement Component.transferFocus.
Component findNextFocusComponent(Component child) Component findNextFocusComponent(Component child)
{ {
int start, end; synchronized (getTreeLock ())
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) int start, end;
{ if (child != null)
// The JCL says that we should wrap here. However, that {
// seems wrong. To me it seems that focus order should be for (start = 0; start < ncomponents; ++start)
// global within in given window. So instead if we reach {
// the end we try to look in our parent, if we have one. if (component[start] == child)
if (parent != null) break;
return parent.findNextFocusComponent(this); }
j -= ncomponents; end = start;
} // This special case lets us be sure to terminate.
if (component[j] instanceof Container) if (end == 0)
{ end = ncomponents;
Component c = component[j]; ++start;
c = c.findNextFocusComponent(null); }
if (c != null) else
return c; {
} start = 0;
else if (component[j].isFocusTraversable()) end = ncomponents;
return component[j]; }
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;
} }
return null;
} }
private void addNotifyContainerChildren() private void addNotifyContainerChildren()
{ {
for (int i = ncomponents; --i >= 0; ) synchronized (getTreeLock ())
{ {
component[i].addNotify(); for (int i = ncomponents; --i >= 0; )
if (component[i].isLightweight()) {
enableEvents(component[i].eventMask); component[i].addNotify();
if (component[i].isLightweight())
enableEvents(component[i].eventMask);
}
} }
} }
...@@ -1190,12 +1233,15 @@ public class Container extends Component ...@@ -1190,12 +1233,15 @@ public class Container extends Component
*/ */
public int getAccessibleChildrenCount() public int getAccessibleChildrenCount()
{ {
int count = 0; synchronized (getTreeLock ())
int i = component == null ? 0 : component.length; {
while (--i >= 0) int count = 0;
if (component[i] instanceof Accessible) int i = component == null ? 0 : component.length;
count++; while (--i >= 0)
return count; if (component[i] instanceof Accessible)
count++;
return count;
}
} }
/** /**
...@@ -1206,15 +1252,18 @@ public class Container extends Component ...@@ -1206,15 +1252,18 @@ public class Container extends Component
*/ */
public Accessible getAccessibleChild(int i) public Accessible getAccessibleChild(int i)
{ {
if (component == null) synchronized (getTreeLock ())
return null; {
int index = -1; if (component == null)
while (i >= 0 && ++index < component.length) return null;
if (component[index] instanceof Accessible) int index = -1;
i--; while (i >= 0 && ++index < component.length)
if (i < 0) if (component[index] instanceof Accessible)
return (Accessible) component[index]; i--;
return null; if (i < 0)
return (Accessible) component[index];
return null;
}
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment