123 |
*/ |
*/ |
124 |
public Component getComponent(int n) |
public Component getComponent(int n) |
125 |
{ |
{ |
126 |
if (n < 0 || n >= ncomponents) |
synchronized (getTreeLock ()) |
127 |
throw new ArrayIndexOutOfBoundsException("no such component"); |
{ |
128 |
return component[n]; |
if (n < 0 || n >= ncomponents) |
129 |
|
throw new ArrayIndexOutOfBoundsException("no such component"); |
130 |
|
return component[n]; |
131 |
|
} |
132 |
} |
} |
133 |
|
|
134 |
/** |
/** |
138 |
*/ |
*/ |
139 |
public Component[] getComponents() |
public Component[] getComponents() |
140 |
{ |
{ |
141 |
Component[] result = new Component[ncomponents]; |
synchronized (getTreeLock ()) |
142 |
if (ncomponents > 0) |
{ |
143 |
System.arraycopy(component, 0, result, 0, ncomponents); |
Component[] result = new Component[ncomponents]; |
144 |
return result; |
if (ncomponents > 0) |
145 |
|
System.arraycopy(component, 0, result, 0, ncomponents); |
146 |
|
return result; |
147 |
|
} |
148 |
} |
} |
149 |
|
|
150 |
/** |
/** |
266 |
*/ |
*/ |
267 |
protected void addImpl(Component comp, Object constraints, int index) |
protected void addImpl(Component comp, Object constraints, int index) |
268 |
{ |
{ |
269 |
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) |
|
270 |
{ |
{ |
271 |
if (layoutMgr instanceof LayoutManager2) |
if (index > ncomponents |
272 |
{ |
|| (index < 0 && index != -1) |
273 |
LayoutManager2 lm2 = (LayoutManager2) layoutMgr; |
|| comp instanceof Window |
274 |
lm2.addLayoutComponent(comp, constraints); |
|| (comp instanceof Container |
275 |
} |
&& ((Container) comp).isAncestorOf(this))) |
276 |
else if (constraints instanceof String) |
throw new IllegalArgumentException(); |
277 |
layoutMgr.addLayoutComponent((String) constraints, comp); |
|
278 |
else |
// Reparent component, and make sure component is instantiated if |
279 |
layoutMgr.addLayoutComponent(null, comp); |
// we are. |
280 |
|
if (comp.parent != null) |
281 |
|
comp.parent.remove(comp); |
282 |
|
comp.parent = this; |
283 |
|
if (peer != null) |
284 |
|
{ |
285 |
|
comp.addNotify(); |
286 |
|
|
287 |
|
if (comp.isLightweight()) |
288 |
|
enableEvents(comp.eventMask); |
289 |
|
} |
290 |
|
|
291 |
|
invalidate(); |
292 |
|
|
293 |
|
if (component == null) |
294 |
|
component = new Component[4]; // FIXME, better initial size? |
295 |
|
|
296 |
|
// This isn't the most efficient implementation. We could do less |
297 |
|
// copying when growing the array. It probably doesn't matter. |
298 |
|
if (ncomponents >= component.length) |
299 |
|
{ |
300 |
|
int nl = component.length * 2; |
301 |
|
Component[] c = new Component[nl]; |
302 |
|
System.arraycopy(component, 0, c, 0, ncomponents); |
303 |
|
component = c; |
304 |
|
} |
305 |
|
if (index == -1) |
306 |
|
component[ncomponents++] = comp; |
307 |
|
else |
308 |
|
{ |
309 |
|
System.arraycopy(component, index, component, index + 1, |
310 |
|
ncomponents - index); |
311 |
|
component[index] = comp; |
312 |
|
++ncomponents; |
313 |
|
} |
314 |
|
|
315 |
|
// Notify the layout manager. |
316 |
|
if (layoutMgr != null) |
317 |
|
{ |
318 |
|
if (layoutMgr instanceof LayoutManager2) |
319 |
|
{ |
320 |
|
LayoutManager2 lm2 = (LayoutManager2) layoutMgr; |
321 |
|
lm2.addLayoutComponent(comp, constraints); |
322 |
|
} |
323 |
|
else if (constraints instanceof String) |
324 |
|
layoutMgr.addLayoutComponent((String) constraints, comp); |
325 |
|
else |
326 |
|
layoutMgr.addLayoutComponent(null, comp); |
327 |
|
} |
328 |
|
|
329 |
|
// Post event to notify of adding the container. |
330 |
|
ContainerEvent ce = new ContainerEvent(this, |
331 |
|
ContainerEvent.COMPONENT_ADDED, |
332 |
|
comp); |
333 |
|
getToolkit().getSystemEventQueue().postEvent(ce); |
334 |
} |
} |
|
|
|
|
// Post event to notify of adding the container. |
|
|
ContainerEvent ce = new ContainerEvent(this, |
|
|
ContainerEvent.COMPONENT_ADDED, |
|
|
comp); |
|
|
getToolkit().getSystemEventQueue().postEvent(ce); |
|
335 |
} |
} |
336 |
|
|
337 |
/** |
/** |
341 |
*/ |
*/ |
342 |
public void remove(int index) |
public void remove(int index) |
343 |
{ |
{ |
344 |
Component r = component[index]; |
synchronized (getTreeLock ()) |
345 |
|
{ |
346 |
|
Component r = component[index]; |
347 |
|
|
348 |
r.removeNotify(); |
r.removeNotify(); |
349 |
|
|
350 |
System.arraycopy(component, index + 1, component, index, |
System.arraycopy(component, index + 1, component, index, |
351 |
ncomponents - index - 1); |
ncomponents - index - 1); |
352 |
component[--ncomponents] = null; |
component[--ncomponents] = null; |
353 |
|
|
354 |
invalidate(); |
invalidate(); |
355 |
|
|
356 |
if (layoutMgr != null) |
if (layoutMgr != null) |
357 |
layoutMgr.removeLayoutComponent(r); |
layoutMgr.removeLayoutComponent(r); |
358 |
|
|
359 |
// Post event to notify of adding the container. |
// Post event to notify of adding the container. |
360 |
ContainerEvent ce = new ContainerEvent(this, |
ContainerEvent ce = new ContainerEvent(this, |
361 |
ContainerEvent.COMPONENT_REMOVED, |
ContainerEvent.COMPONENT_REMOVED, |
362 |
r); |
r); |
363 |
getToolkit().getSystemEventQueue().postEvent(ce); |
getToolkit().getSystemEventQueue().postEvent(ce); |
364 |
|
} |
365 |
} |
} |
366 |
|
|
367 |
/** |
/** |
371 |
*/ |
*/ |
372 |
public void remove(Component comp) |
public void remove(Component comp) |
373 |
{ |
{ |
374 |
for (int i = 0; i < ncomponents; ++i) |
synchronized (getTreeLock ()) |
375 |
{ |
{ |
376 |
if (component[i] == comp) |
for (int i = 0; i < ncomponents; ++i) |
377 |
{ |
{ |
378 |
remove(i); |
if (component[i] == comp) |
379 |
break; |
{ |
380 |
} |
remove(i); |
381 |
|
break; |
382 |
|
} |
383 |
|
} |
384 |
} |
} |
385 |
} |
} |
386 |
|
|
389 |
*/ |
*/ |
390 |
public void removeAll() |
public void removeAll() |
391 |
{ |
{ |
392 |
while (ncomponents > 0) |
synchronized (getTreeLock ()) |
393 |
remove(0); |
{ |
394 |
|
while (ncomponents > 0) |
395 |
|
remove(0); |
396 |
|
} |
397 |
} |
} |
398 |
|
|
399 |
/** |
/** |
451 |
*/ |
*/ |
452 |
public void validate() |
public void validate() |
453 |
{ |
{ |
454 |
// FIXME: use the tree lock? |
synchronized (getTreeLock ()) |
|
synchronized (this) |
|
455 |
{ |
{ |
456 |
if (! isValid()) |
if (! isValid()) |
457 |
{ |
{ |
730 |
{ |
{ |
731 |
if (e instanceof ContainerEvent) |
if (e instanceof ContainerEvent) |
732 |
processContainerEvent((ContainerEvent) e); |
processContainerEvent((ContainerEvent) e); |
733 |
else super.processEvent(e); |
else |
734 |
|
super.processEvent(e); |
735 |
} |
} |
736 |
|
|
737 |
/** |
/** |
782 |
*/ |
*/ |
783 |
public Component getComponentAt(int x, int y) |
public Component getComponentAt(int x, int y) |
784 |
{ |
{ |
785 |
if (! contains(x, y)) |
synchronized (getTreeLock ()) |
|
return null; |
|
|
for (int i = 0; i < ncomponents; ++i) |
|
786 |
{ |
{ |
787 |
// Ignore invisible children... |
if (! contains(x, y)) |
788 |
if (!component[i].isVisible()) |
return null; |
789 |
continue; |
for (int i = 0; i < ncomponents; ++i) |
790 |
|
{ |
791 |
int x2 = x - component[i].x; |
// Ignore invisible children... |
792 |
int y2 = y - component[i].y; |
if (!component[i].isVisible()) |
793 |
if (component[i].contains(x2, y2)) |
continue; |
794 |
return component[i]; |
|
795 |
|
int x2 = x - component[i].x; |
796 |
|
int y2 = y - component[i].y; |
797 |
|
if (component[i].contains(x2, y2)) |
798 |
|
return component[i]; |
799 |
|
} |
800 |
|
return this; |
801 |
} |
} |
|
return this; |
|
802 |
} |
} |
803 |
|
|
804 |
/** |
/** |
839 |
|
|
840 |
public Component findComponentAt(int x, int y) |
public Component findComponentAt(int x, int y) |
841 |
{ |
{ |
842 |
if (! contains(x, y)) |
synchronized (getTreeLock ()) |
|
return null; |
|
|
|
|
|
for (int i = 0; i < ncomponents; ++i) |
|
843 |
{ |
{ |
844 |
// Ignore invisible children... |
if (! contains(x, y)) |
845 |
if (!component[i].isVisible()) |
return null; |
|
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]; |
|
|
} |
|
846 |
|
|
847 |
return this; |
for (int i = 0; i < ncomponents; ++i) |
848 |
|
{ |
849 |
|
// Ignore invisible children... |
850 |
|
if (!component[i].isVisible()) |
851 |
|
continue; |
852 |
|
|
853 |
|
int x2 = x - component[i].x; |
854 |
|
int y2 = y - component[i].y; |
855 |
|
// We don't do the contains() check right away because |
856 |
|
// findComponentAt would redundantly do it first thing. |
857 |
|
if (component[i] instanceof Container) |
858 |
|
{ |
859 |
|
Container k = (Container) component[i]; |
860 |
|
Component r = k.findComponentAt(x2, y2); |
861 |
|
if (r != null) |
862 |
|
return r; |
863 |
|
} |
864 |
|
else if (component[i].contains(x2, y2)) |
865 |
|
return component[i]; |
866 |
|
} |
867 |
|
|
868 |
|
return this; |
869 |
|
} |
870 |
} |
} |
871 |
|
|
872 |
public Component findComponentAt(Point p) |
public Component findComponentAt(Point p) |
892 |
*/ |
*/ |
893 |
public void removeNotify() |
public void removeNotify() |
894 |
{ |
{ |
895 |
for (int i = 0; i < ncomponents; ++i) |
synchronized (getTreeLock ()) |
896 |
component[i].removeNotify(); |
{ |
897 |
super.removeNotify(); |
for (int i = 0; i < ncomponents; ++i) |
898 |
|
component[i].removeNotify(); |
899 |
|
super.removeNotify(); |
900 |
|
} |
901 |
} |
} |
902 |
|
|
903 |
/** |
/** |
907 |
* @param component The component to test. |
* @param component The component to test. |
908 |
* |
* |
909 |
* @return <code>true</code> if this container is an ancestor of the |
* @return <code>true</code> if this container is an ancestor of the |
910 |
* specified component, <code>false</code>. |
* specified component, <code>false</code> otherwise. |
911 |
*/ |
*/ |
912 |
public boolean isAncestorOf(Component comp) |
public boolean isAncestorOf(Component comp) |
913 |
{ |
{ |
914 |
while (true) |
synchronized (getTreeLock ()) |
915 |
{ |
{ |
916 |
if (comp == null) |
while (true) |
917 |
return false; |
{ |
918 |
if (comp == this) |
if (comp == null) |
919 |
return true; |
return false; |
920 |
comp = comp.getParent(); |
if (comp == this) |
921 |
|
return true; |
922 |
|
comp = comp.getParent(); |
923 |
|
} |
924 |
} |
} |
925 |
} |
} |
926 |
|
|
948 |
*/ |
*/ |
949 |
public void list(PrintStream out, int indent) |
public void list(PrintStream out, int indent) |
950 |
{ |
{ |
951 |
super.list(out, indent); |
synchronized (getTreeLock ()) |
952 |
for (int i = 0; i < ncomponents; ++i) |
{ |
953 |
component[i].list(out, indent + 2); |
super.list(out, indent); |
954 |
|
for (int i = 0; i < ncomponents; ++i) |
955 |
|
component[i].list(out, indent + 2); |
956 |
|
} |
957 |
} |
} |
958 |
|
|
959 |
/** |
/** |
965 |
*/ |
*/ |
966 |
public void list(PrintWriter out, int indent) |
public void list(PrintWriter out, int indent) |
967 |
{ |
{ |
968 |
super.list(out, indent); |
synchronized (getTreeLock ()) |
969 |
for (int i = 0; i < ncomponents; ++i) |
{ |
970 |
component[i].list(out, indent + 2); |
super.list(out, indent); |
971 |
|
for (int i = 0; i < ncomponents; ++i) |
972 |
|
component[i].list(out, indent + 2); |
973 |
|
} |
974 |
} |
} |
975 |
|
|
976 |
public void setFocusTraversalKeys(int id, Set keys) |
public void setFocusTraversalKeys(int id, Set keys) |
1042 |
private void visitChildren(Graphics gfx, GfxVisitor visitor, |
private void visitChildren(Graphics gfx, GfxVisitor visitor, |
1043 |
boolean lightweightOnly) |
boolean lightweightOnly) |
1044 |
{ |
{ |
1045 |
// FIXME: do locking |
synchronized (getTreeLock ()) |
|
|
|
|
for (int i = 0; i < ncomponents; ++i) |
|
1046 |
{ |
{ |
1047 |
Component comp = component[i]; |
for (int i = 0; i < ncomponents; ++i) |
1048 |
boolean applicable = comp.isVisible() |
{ |
1049 |
&& (comp.isLightweight() || !lightweightOnly); |
Component comp = component[i]; |
1050 |
|
boolean applicable = comp.isVisible() |
1051 |
if (applicable) |
&& (comp.isLightweight() || !lightweightOnly); |
1052 |
visitChild(gfx, visitor, comp); |
|
1053 |
|
if (applicable) |
1054 |
|
visitChild(gfx, visitor, comp); |
1055 |
|
} |
1056 |
} |
} |
1057 |
} |
} |
1058 |
|
|
1098 |
// This is used to implement Component.transferFocus. |
// This is used to implement Component.transferFocus. |
1099 |
Component findNextFocusComponent(Component child) |
Component findNextFocusComponent(Component child) |
1100 |
{ |
{ |
1101 |
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 |
|
1102 |
{ |
{ |
1103 |
start = 0; |
int start, end; |
1104 |
end = ncomponents; |
if (child != null) |
1105 |
} |
{ |
1106 |
|
for (start = 0; start < ncomponents; ++start) |
1107 |
|
{ |
1108 |
|
if (component[start] == child) |
1109 |
|
break; |
1110 |
|
} |
1111 |
|
end = start; |
1112 |
|
// This special case lets us be sure to terminate. |
1113 |
|
if (end == 0) |
1114 |
|
end = ncomponents; |
1115 |
|
++start; |
1116 |
|
} |
1117 |
|
else |
1118 |
|
{ |
1119 |
|
start = 0; |
1120 |
|
end = ncomponents; |
1121 |
|
} |
1122 |
|
|
1123 |
|
for (int j = start; j != end; ++j) |
1124 |
|
{ |
1125 |
|
if (j >= ncomponents) |
1126 |
|
{ |
1127 |
|
// The JCL says that we should wrap here. However, that |
1128 |
|
// seems wrong. To me it seems that focus order should be |
1129 |
|
// global within in given window. So instead if we reach |
1130 |
|
// the end we try to look in our parent, if we have one. |
1131 |
|
if (parent != null) |
1132 |
|
return parent.findNextFocusComponent(this); |
1133 |
|
j -= ncomponents; |
1134 |
|
} |
1135 |
|
if (component[j] instanceof Container) |
1136 |
|
{ |
1137 |
|
Component c = component[j]; |
1138 |
|
c = c.findNextFocusComponent(null); |
1139 |
|
if (c != null) |
1140 |
|
return c; |
1141 |
|
} |
1142 |
|
else if (component[j].isFocusTraversable()) |
1143 |
|
return component[j]; |
1144 |
|
} |
1145 |
|
|
1146 |
for (int j = start; j != end; ++j) |
return null; |
|
{ |
|
|
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]; |
|
1147 |
} |
} |
|
|
|
|
return null; |
|
1148 |
} |
} |
1149 |
|
|
1150 |
private void addNotifyContainerChildren() |
private void addNotifyContainerChildren() |
1151 |
{ |
{ |
1152 |
for (int i = ncomponents; --i >= 0; ) |
synchronized (getTreeLock ()) |
1153 |
{ |
{ |
1154 |
component[i].addNotify(); |
for (int i = ncomponents; --i >= 0; ) |
1155 |
if (component[i].isLightweight()) |
{ |
1156 |
enableEvents(component[i].eventMask); |
component[i].addNotify(); |
1157 |
|
if (component[i].isLightweight()) |
1158 |
|
enableEvents(component[i].eventMask); |
1159 |
|
} |
1160 |
} |
} |
1161 |
} |
} |
1162 |
|
|
1233 |
*/ |
*/ |
1234 |
public int getAccessibleChildrenCount() |
public int getAccessibleChildrenCount() |
1235 |
{ |
{ |
1236 |
int count = 0; |
synchronized (getTreeLock ()) |
1237 |
int i = component == null ? 0 : component.length; |
{ |
1238 |
while (--i >= 0) |
int count = 0; |
1239 |
if (component[i] instanceof Accessible) |
int i = component == null ? 0 : component.length; |
1240 |
count++; |
while (--i >= 0) |
1241 |
return count; |
if (component[i] instanceof Accessible) |
1242 |
|
count++; |
1243 |
|
return count; |
1244 |
|
} |
1245 |
} |
} |
1246 |
|
|
1247 |
/** |
/** |
1252 |
*/ |
*/ |
1253 |
public Accessible getAccessibleChild(int i) |
public Accessible getAccessibleChild(int i) |
1254 |
{ |
{ |
1255 |
if (component == null) |
synchronized (getTreeLock ()) |
1256 |
return null; |
{ |
1257 |
int index = -1; |
if (component == null) |
1258 |
while (i >= 0 && ++index < component.length) |
return null; |
1259 |
if (component[index] instanceof Accessible) |
int index = -1; |
1260 |
i--; |
while (i >= 0 && ++index < component.length) |
1261 |
if (i < 0) |
if (component[index] instanceof Accessible) |
1262 |
return (Accessible) component[index]; |
i--; |
1263 |
return null; |
if (i < 0) |
1264 |
|
return (Accessible) component[index]; |
1265 |
|
return null; |
1266 |
|
} |
1267 |
} |
} |
1268 |
|
|
1269 |
/** |
/** |