1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
63: import ;
64:
65: import ;
66:
67:
79: public class Container extends Component
80: {
81:
84: private static final long serialVersionUID = 4613797578919906343L;
85:
86:
87: int ncomponents;
88: Component[] component;
89: LayoutManager layoutMgr;
90:
91: LightweightDispatcher dispatcher;
92:
93: Dimension maxSize;
94:
95:
98: boolean focusCycleRoot;
99:
100: int containerSerializedDataVersion;
101:
102:
103: transient ContainerListener containerListener;
104: transient PropertyChangeSupport changeSupport;
105:
106:
108: private FocusTraversalPolicy focusTraversalPolicy;
109:
110:
119: transient Set[] focusTraversalKeys;
120:
121:
124: public Container()
125: {
126:
127: }
128:
129:
134: public int getComponentCount()
135: {
136: return countComponents ();
137: }
138:
139:
146: public int countComponents()
147: {
148: return ncomponents;
149: }
150:
151:
160: public Component getComponent(int n)
161: {
162: synchronized (getTreeLock ())
163: {
164: if (n < 0 || n >= ncomponents)
165: throw new ArrayIndexOutOfBoundsException("no such component");
166:
167: return component[n];
168: }
169: }
170:
171:
176: public Component[] getComponents()
177: {
178: synchronized (getTreeLock ())
179: {
180: Component[] result = new Component[ncomponents];
181:
182: if (ncomponents > 0)
183: System.arraycopy(component, 0, result, 0, ncomponents);
184:
185: return result;
186: }
187: }
188:
189:
192:
193: protected void swapComponents (int i, int j)
194: {
195: synchronized (getTreeLock ())
196: {
197: if (i < 0
198: || i >= component.length
199: || j < 0
200: || j >= component.length)
201: throw new ArrayIndexOutOfBoundsException ();
202: Component tmp = component[i];
203: component[i] = component[j];
204: component[j] = tmp;
205: }
206: }
207:
208:
214: public Insets getInsets()
215: {
216: return insets ();
217: }
218:
219:
226: public Insets insets()
227: {
228: if (peer == null)
229: return new Insets (0, 0, 0, 0);
230:
231: return ((ContainerPeer) peer).getInsets ();
232: }
233:
234:
242: public Component add(Component comp)
243: {
244: addImpl(comp, null, -1);
245: return comp;
246: }
247:
248:
260: public Component add(String name, Component comp)
261: {
262: addImpl(comp, name, -1);
263: return comp;
264: }
265:
266:
278: public Component add(Component comp, int index)
279: {
280: addImpl(comp, null, index);
281: return comp;
282: }
283:
284:
292: public void add(Component comp, Object constraints)
293: {
294: addImpl(comp, constraints, -1);
295: }
296:
297:
309: public void add(Component comp, Object constraints, int index)
310: {
311: addImpl(comp, constraints, index);
312: }
313:
314:
329: protected void addImpl(Component comp, Object constraints, int index)
330: {
331: synchronized (getTreeLock ())
332: {
333: if (index > ncomponents
334: || (index < 0 && index != -1)
335: || comp instanceof Window
336: || (comp instanceof Container
337: && ((Container) comp).isAncestorOf(this)))
338: throw new IllegalArgumentException();
339:
340:
341:
342: if (comp.parent != null)
343: comp.parent.remove(comp);
344: comp.parent = this;
345:
346: if (peer != null)
347: {
348:
349: comp.addNotify();
350:
351: if (comp.isLightweight ())
352: {
353: enableEvents (comp.eventMask);
354: if (!isLightweight ())
355: enableEvents (AWTEvent.PAINT_EVENT_MASK);
356: }
357: }
358:
359:
360: comp.invalidate();
361:
362: if (component == null)
363: component = new Component[4];
364:
365:
366:
367: if (ncomponents >= component.length)
368: {
369: int nl = component.length * 2;
370: Component[] c = new Component[nl];
371: System.arraycopy(component, 0, c, 0, ncomponents);
372: component = c;
373: }
374:
375: if (index == -1)
376: component[ncomponents++] = comp;
377: else
378: {
379: System.arraycopy(component, index, component, index + 1,
380: ncomponents - index);
381: component[index] = comp;
382: ++ncomponents;
383: }
384:
385:
386: if (layoutMgr != null)
387: {
388: if (layoutMgr instanceof LayoutManager2)
389: {
390: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
391: lm2.addLayoutComponent(comp, constraints);
392: }
393: else if (constraints instanceof String)
394: layoutMgr.addLayoutComponent((String) constraints, comp);
395: else
396: layoutMgr.addLayoutComponent(null, comp);
397: }
398:
399:
400:
401:
402:
403: ContainerEvent ce = new ContainerEvent(this,
404: ContainerEvent.COMPONENT_ADDED,
405: comp);
406: ContainerListener[] listeners = getContainerListeners();
407: for (int i = 0; i < listeners.length; i++)
408: listeners[i].componentAdded(ce);
409:
410:
411: repaint(comp.getX(), comp.getY(), comp.getWidth(),
412: comp.getHeight());
413: }
414: }
415:
416:
421: public void remove(int index)
422: {
423: synchronized (getTreeLock ())
424: {
425: Component r = component[index];
426:
427: ComponentListener[] list = r.getComponentListeners();
428: for (int j = 0; j < list.length; j++)
429: r.removeComponentListener(list[j]);
430:
431: if (r.isShowing())
432: r.removeNotify();
433:
434: System.arraycopy(component, index + 1, component, index,
435: ncomponents - index - 1);
436: component[--ncomponents] = null;
437:
438: invalidate();
439:
440: if (layoutMgr != null)
441: layoutMgr.removeLayoutComponent(r);
442:
443: r.parent = null;
444:
445: if (isShowing ())
446: {
447:
448: ContainerEvent ce = new ContainerEvent(this,
449: ContainerEvent.COMPONENT_REMOVED,
450: r);
451: getToolkit().getSystemEventQueue().postEvent(ce);
452: }
453: }
454: }
455:
456:
461: public void remove(Component comp)
462: {
463: synchronized (getTreeLock ())
464: {
465: for (int i = 0; i < ncomponents; ++i)
466: {
467: if (component[i] == comp)
468: {
469: remove(i);
470: break;
471: }
472: }
473: }
474: }
475:
476:
479: public void removeAll()
480: {
481: synchronized (getTreeLock ())
482: {
483: while (ncomponents > 0)
484: remove(0);
485: }
486: }
487:
488:
493: public LayoutManager getLayout()
494: {
495: return layoutMgr;
496: }
497:
498:
504: public void setLayout(LayoutManager mgr)
505: {
506: layoutMgr = mgr;
507: invalidate();
508: }
509:
510:
513: public void doLayout()
514: {
515: layout ();
516: }
517:
518:
523: public void layout()
524: {
525: if (layoutMgr != null)
526: layoutMgr.layoutContainer (this);
527: }
528:
529:
533: public void invalidate()
534: {
535: super.invalidate();
536: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
537: {
538: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
539: lm2.invalidateLayout(this);
540: }
541: }
542:
543:
546: public void validate()
547: {
548: synchronized (getTreeLock ())
549: {
550: if (! isValid() && peer != null)
551: {
552: validateTree();
553: }
554: }
555: }
556:
557:
560: void invalidateTree()
561: {
562: super.invalidate();
563: for (int i = 0; i < ncomponents; i++)
564: {
565: Component comp = component[i];
566: comp.invalidate();
567: if (comp instanceof Container)
568: ((Container) comp).invalidateTree();
569: }
570:
571: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
572: {
573: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
574: lm2.invalidateLayout(this);
575: }
576: }
577:
578:
582: protected void validateTree()
583: {
584: if (valid)
585: return;
586:
587: ContainerPeer cPeer = null;
588: if (peer != null && ! (peer instanceof LightweightPeer))
589: {
590: cPeer = (ContainerPeer) peer;
591: cPeer.beginValidate();
592: }
593:
594: for (int i = 0; i < ncomponents; ++i)
595: {
596: Component comp = component[i];
597:
598: if (comp.getPeer () == null)
599: comp.addNotify();
600: }
601:
602: doLayout ();
603: for (int i = 0; i < ncomponents; ++i)
604: {
605: Component comp = component[i];
606:
607: if (! comp.isValid())
608: {
609: if (comp instanceof Container)
610: {
611: ((Container) comp).validateTree();
612: }
613: else
614: {
615: component[i].validate();
616: }
617: }
618: }
619:
620:
623: valid = true;
624:
625: if (cPeer != null)
626: cPeer.endValidate();
627: }
628:
629: public void setFont(Font f)
630: {
631: if( (f != null && (font == null || !font.equals(f)))
632: || f == null)
633: {
634: super.setFont(f);
635:
636:
637:
638: invalidateTree();
639: }
640: }
641:
642:
647: public Dimension getPreferredSize()
648: {
649: return preferredSize ();
650: }
651:
652:
659: public Dimension preferredSize()
660: {
661: synchronized(treeLock)
662: {
663: if(valid && prefSize != null)
664: return new Dimension(prefSize);
665: LayoutManager layout = getLayout();
666: if (layout != null)
667: {
668: Dimension layoutSize = layout.preferredLayoutSize(this);
669: if(valid)
670: prefSize = layoutSize;
671: return new Dimension(layoutSize);
672: }
673: else
674: return super.preferredSize ();
675: }
676: }
677:
678:
683: public Dimension getMinimumSize()
684: {
685: return minimumSize ();
686: }
687:
688:
695: public Dimension minimumSize()
696: {
697: if(valid && minSize != null)
698: return new Dimension(minSize);
699:
700: LayoutManager layout = getLayout();
701: if (layout != null)
702: {
703: minSize = layout.minimumLayoutSize (this);
704: return minSize;
705: }
706: else
707: return super.minimumSize ();
708: }
709:
710:
715: public Dimension getMaximumSize()
716: {
717: if (valid && maxSize != null)
718: return new Dimension(maxSize);
719:
720: LayoutManager layout = getLayout();
721: if (layout != null && layout instanceof LayoutManager2)
722: {
723: LayoutManager2 lm2 = (LayoutManager2) layout;
724: maxSize = lm2.maximumLayoutSize(this);
725: return maxSize;
726: }
727: else
728: return super.getMaximumSize();
729: }
730:
731:
738: public float getAlignmentX()
739: {
740: LayoutManager layout = getLayout();
741: float alignmentX = 0.0F;
742: if (layout != null && layout instanceof LayoutManager2)
743: {
744: LayoutManager2 lm2 = (LayoutManager2) layout;
745: alignmentX = lm2.getLayoutAlignmentX(this);
746: }
747: else
748: alignmentX = super.getAlignmentX();
749: return alignmentX;
750: }
751:
752:
759: public float getAlignmentY()
760: {
761: LayoutManager layout = getLayout();
762: float alignmentY = 0.0F;
763: if (layout != null && layout instanceof LayoutManager2)
764: {
765: LayoutManager2 lm2 = (LayoutManager2) layout;
766: alignmentY = lm2.getLayoutAlignmentY(this);
767: }
768: else
769: alignmentY = super.getAlignmentY();
770: return alignmentY;
771: }
772:
773:
782: public void paint(Graphics g)
783: {
784: if (!isShowing())
785: return;
786:
787:
788:
789: visitChildren(g, GfxPaintVisitor.INSTANCE, false);
790: }
791:
792:
809: public void update(Graphics g)
810: {
811:
812:
813:
814:
815:
816:
817:
818:
819: ComponentPeer p = peer;
820: if (p != null && !(p instanceof LightweightPeer))
821: g.clearRect(0, 0, getWidth(), getHeight());
822:
823: paint(g);
824: }
825:
826:
835: public void print(Graphics g)
836: {
837: super.print(g);
838: visitChildren(g, GfxPrintVisitor.INSTANCE, true);
839: }
840:
841:
846: public void paintComponents(Graphics g)
847: {
848: paint(g);
849: visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
850: }
851:
852:
857: public void printComponents(Graphics g)
858: {
859: super.paint(g);
860: visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
861: }
862:
863:
869: public synchronized void addContainerListener(ContainerListener listener)
870: {
871: containerListener = AWTEventMulticaster.add(containerListener, listener);
872: }
873:
874:
880: public synchronized void removeContainerListener(ContainerListener listener)
881: {
882: containerListener = AWTEventMulticaster.remove(containerListener, listener);
883: }
884:
885:
888: public synchronized ContainerListener[] getContainerListeners()
889: {
890: return (ContainerListener[])
891: AWTEventMulticaster.getListeners(containerListener,
892: ContainerListener.class);
893: }
894:
895:
913: public EventListener[] getListeners(Class listenerType)
914: {
915: if (listenerType == ContainerListener.class)
916: return getContainerListeners();
917: return super.getListeners(listenerType);
918: }
919:
920:
928: protected void processEvent(AWTEvent e)
929: {
930: if (e instanceof ContainerEvent)
931: processContainerEvent((ContainerEvent) e);
932: else
933: super.processEvent(e);
934: }
935:
936:
942: protected void processContainerEvent(ContainerEvent e)
943: {
944: if (containerListener == null)
945: return;
946: switch (e.id)
947: {
948: case ContainerEvent.COMPONENT_ADDED:
949: containerListener.componentAdded(e);
950: break;
951:
952: case ContainerEvent.COMPONENT_REMOVED:
953: containerListener.componentRemoved(e);
954: break;
955: }
956: }
957:
958:
965: public void deliverEvent(Event e)
966: {
967: if (!handleEvent (e))
968: {
969: synchronized (getTreeLock ())
970: {
971: Component parent = getParent ();
972:
973: if (parent != null)
974: parent.deliverEvent (e);
975: }
976: }
977: }
978:
979:
993: public Component getComponentAt(int x, int y)
994: {
995: return locate (x, y);
996: }
997:
998:
1014: public Component locate(int x, int y)
1015: {
1016: synchronized (getTreeLock ())
1017: {
1018: if (!contains (x, y))
1019: return null;
1020: for (int i = 0; i < ncomponents; ++i)
1021: {
1022:
1023: if (!component[i].isVisible ())
1024: continue;
1025:
1026: int x2 = x - component[i].x;
1027: int y2 = y - component[i].y;
1028: if (component[i].contains (x2, y2))
1029: return component[i];
1030: }
1031: return this;
1032: }
1033: }
1034:
1035:
1047: public Component getComponentAt(Point p)
1048: {
1049: return getComponentAt (p.x, p.y);
1050: }
1051:
1052: public Component findComponentAt(int x, int y)
1053: {
1054: synchronized (getTreeLock ())
1055: {
1056: if (! contains(x, y))
1057: return null;
1058:
1059: for (int i = 0; i < ncomponents; ++i)
1060: {
1061:
1062: if (!component[i].isVisible())
1063: continue;
1064:
1065: int x2 = x - component[i].x;
1066: int y2 = y - component[i].y;
1067:
1068:
1069: if (component[i] instanceof Container)
1070: {
1071: Container k = (Container) component[i];
1072: Component r = k.findComponentAt(x2, y2);
1073: if (r != null)
1074: return r;
1075: }
1076: else if (component[i].contains(x2, y2))
1077: return component[i];
1078: }
1079:
1080: return this;
1081: }
1082: }
1083:
1084:
1096: Component findComponentForMouseEventAt(int x, int y)
1097: {
1098: synchronized (getTreeLock())
1099: {
1100: if (!contains(x, y))
1101: return null;
1102:
1103: for (int i = 0; i < ncomponents; ++i)
1104: {
1105:
1106: if (!component[i].isVisible())
1107: continue;
1108:
1109: int x2 = x - component[i].x;
1110: int y2 = y - component[i].y;
1111:
1112:
1113: if (component[i] instanceof Container)
1114: {
1115: Container k = (Container) component[i];
1116: Component r = k.findComponentForMouseEventAt(x2, y2);
1117: if (r != null)
1118: return r;
1119: }
1120: else if (component[i].contains(x2, y2))
1121: return component[i];
1122: }
1123:
1124:
1125: if (getMouseListeners().length == 0
1126: && getMouseMotionListeners().length == 0)
1127: return null;
1128: return this;
1129: }
1130: }
1131:
1132: public Component findComponentAt(Point p)
1133: {
1134: return findComponentAt(p.x, p.y);
1135: }
1136:
1137:
1142: public void addNotify()
1143: {
1144: super.addNotify();
1145: addNotifyContainerChildren();
1146: }
1147:
1148:
1153: public void removeNotify()
1154: {
1155: synchronized (getTreeLock ())
1156: {
1157: for (int i = 0; i < ncomponents; ++i)
1158: component[i].removeNotify();
1159: super.removeNotify();
1160: }
1161: }
1162:
1163:
1172: public boolean isAncestorOf(Component comp)
1173: {
1174: synchronized (getTreeLock ())
1175: {
1176: while (true)
1177: {
1178: if (comp == null)
1179: return false;
1180: if (comp == this)
1181: return true;
1182: comp = comp.getParent();
1183: }
1184: }
1185: }
1186:
1187:
1193: protected String paramString()
1194: {
1195: if (layoutMgr == null)
1196: return super.paramString();
1197:
1198: StringBuffer sb = new StringBuffer();
1199: sb.append(super.paramString());
1200: sb.append(",layout=");
1201: sb.append(layoutMgr.getClass().getName());
1202: return sb.toString();
1203: }
1204:
1205:
1212: public void list(PrintStream out, int indent)
1213: {
1214: synchronized (getTreeLock ())
1215: {
1216: super.list(out, indent);
1217: for (int i = 0; i < ncomponents; ++i)
1218: component[i].list(out, indent + 2);
1219: }
1220: }
1221:
1222:
1229: public void list(PrintWriter out, int indent)
1230: {
1231: synchronized (getTreeLock ())
1232: {
1233: super.list(out, indent);
1234: for (int i = 0; i < ncomponents; ++i)
1235: component[i].list(out, indent + 2);
1236: }
1237: }
1238:
1239:
1255: public void setFocusTraversalKeys(int id, Set keystrokes)
1256: {
1257: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1258: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1259: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1260: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1261: throw new IllegalArgumentException ();
1262:
1263: if (keystrokes == null)
1264: {
1265: Container parent = getParent ();
1266:
1267: while (parent != null)
1268: {
1269: if (parent.areFocusTraversalKeysSet (id))
1270: {
1271: keystrokes = parent.getFocusTraversalKeys (id);
1272: break;
1273: }
1274: parent = parent.getParent ();
1275: }
1276:
1277: if (keystrokes == null)
1278: keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
1279: getDefaultFocusTraversalKeys (id);
1280: }
1281:
1282: Set sa;
1283: Set sb;
1284: Set sc;
1285: String name;
1286: switch (id)
1287: {
1288: case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
1289: sa = getFocusTraversalKeys
1290: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1291: sb = getFocusTraversalKeys
1292: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1293: sc = getFocusTraversalKeys
1294: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1295: name = "forwardFocusTraversalKeys";
1296: break;
1297: case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
1298: sa = getFocusTraversalKeys
1299: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1300: sb = getFocusTraversalKeys
1301: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1302: sc = getFocusTraversalKeys
1303: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1304: name = "backwardFocusTraversalKeys";
1305: break;
1306: case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
1307: sa = getFocusTraversalKeys
1308: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1309: sb = getFocusTraversalKeys
1310: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1311: sc = getFocusTraversalKeys
1312: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1313: name = "upCycleFocusTraversalKeys";
1314: break;
1315: case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
1316: sa = getFocusTraversalKeys
1317: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1318: sb = getFocusTraversalKeys
1319: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1320: sc = getFocusTraversalKeys
1321: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1322: name = "downCycleFocusTraversalKeys";
1323: break;
1324: default:
1325: throw new IllegalArgumentException ();
1326: }
1327:
1328: int i = keystrokes.size ();
1329: Iterator iter = keystrokes.iterator ();
1330:
1331: while (--i >= 0)
1332: {
1333: Object o = iter.next ();
1334: if (!(o instanceof AWTKeyStroke)
1335: || sa.contains (o) || sb.contains (o) || sc.contains (o)
1336: || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
1337: throw new IllegalArgumentException ();
1338: }
1339:
1340: if (focusTraversalKeys == null)
1341: focusTraversalKeys = new Set[4];
1342:
1343: keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
1344: firePropertyChange (name, focusTraversalKeys[id], keystrokes);
1345:
1346: focusTraversalKeys[id] = keystrokes;
1347: }
1348:
1349:
1361: public Set getFocusTraversalKeys (int id)
1362: {
1363: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1364: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1365: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1366: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1367: throw new IllegalArgumentException ();
1368:
1369: Set s = null;
1370:
1371: if (focusTraversalKeys != null)
1372: s = focusTraversalKeys[id];
1373:
1374: if (s == null && parent != null)
1375: s = parent.getFocusTraversalKeys (id);
1376:
1377: return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
1378: .getDefaultFocusTraversalKeys(id)) : s;
1379: }
1380:
1381:
1395: public boolean areFocusTraversalKeysSet (int id)
1396: {
1397: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1398: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1399: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1400: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1401: throw new IllegalArgumentException ();
1402:
1403: return focusTraversalKeys != null && focusTraversalKeys[id] != null;
1404: }
1405:
1406:
1421: public boolean isFocusCycleRoot (Container c)
1422: {
1423: if (this == c
1424: && isFocusCycleRoot ())
1425: return true;
1426:
1427: Container ancestor = getFocusCycleRootAncestor ();
1428:
1429: if (c == ancestor)
1430: return true;
1431:
1432: return false;
1433: }
1434:
1435:
1447: public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
1448: {
1449: focusTraversalPolicy = policy;
1450: }
1451:
1452:
1463: public FocusTraversalPolicy getFocusTraversalPolicy ()
1464: {
1465: if (!isFocusCycleRoot ())
1466: return null;
1467:
1468: if (focusTraversalPolicy == null)
1469: {
1470: Container ancestor = getFocusCycleRootAncestor ();
1471:
1472: if (ancestor != this)
1473: return ancestor.getFocusTraversalPolicy ();
1474: else
1475: {
1476: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1477:
1478: return manager.getDefaultFocusTraversalPolicy ();
1479: }
1480: }
1481: else
1482: return focusTraversalPolicy;
1483: }
1484:
1485:
1493: public boolean isFocusTraversalPolicySet ()
1494: {
1495: return focusTraversalPolicy == null;
1496: }
1497:
1498:
1514: public void setFocusCycleRoot (boolean focusCycleRoot)
1515: {
1516: this.focusCycleRoot = focusCycleRoot;
1517: }
1518:
1519:
1526: public boolean isFocusCycleRoot ()
1527: {
1528: return focusCycleRoot;
1529: }
1530:
1531:
1540: public void transferFocusDownCycle ()
1541: {
1542: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1543:
1544: manager.downFocusCycle (this);
1545: }
1546:
1547:
1555: public void applyComponentOrientation (ComponentOrientation orientation)
1556: {
1557: if (orientation == null)
1558: throw new NullPointerException ();
1559: }
1560:
1561: public void addPropertyChangeListener (PropertyChangeListener listener)
1562: {
1563: if (listener == null)
1564: return;
1565:
1566: if (changeSupport == null)
1567: changeSupport = new PropertyChangeSupport (this);
1568:
1569: changeSupport.addPropertyChangeListener (listener);
1570: }
1571:
1572: public void addPropertyChangeListener (String name,
1573: PropertyChangeListener listener)
1574: {
1575: if (listener == null)
1576: return;
1577:
1578: if (changeSupport == null)
1579: changeSupport = new PropertyChangeSupport (this);
1580:
1581: changeSupport.addPropertyChangeListener (name, listener);
1582: }
1583:
1584:
1585:
1586:
1600: private void visitChildren(Graphics gfx, GfxVisitor visitor,
1601: boolean lightweightOnly)
1602: {
1603: synchronized (getTreeLock ())
1604: {
1605: for (int i = ncomponents - 1; i >= 0; --i)
1606: {
1607: Component comp = component[i];
1608: boolean applicable = comp.isVisible()
1609: && (comp.isLightweight() || !lightweightOnly);
1610:
1611: if (applicable)
1612: visitChild(gfx, visitor, comp);
1613: }
1614: }
1615: }
1616:
1617:
1630: private void visitChild(Graphics gfx, GfxVisitor visitor,
1631: Component comp)
1632: {
1633: Rectangle bounds = comp.getBounds();
1634:
1635: if(!gfx.hitClip(bounds.x,bounds.y, bounds.width, bounds.height))
1636: return;
1637:
1638: Graphics g2 = gfx.create(bounds.x, bounds.y, bounds.width,
1639: bounds.height);
1640: try
1641: {
1642: visitor.visit(comp, g2);
1643: }
1644: finally
1645: {
1646: g2.dispose();
1647: }
1648: }
1649:
1650: void dispatchEventImpl(AWTEvent e)
1651: {
1652:
1653: if (dispatcher != null && dispatcher.handleEvent (e))
1654: return;
1655:
1656: if ((e.id <= ContainerEvent.CONTAINER_LAST
1657: && e.id >= ContainerEvent.CONTAINER_FIRST)
1658: && (containerListener != null
1659: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
1660: processEvent(e);
1661: else
1662: super.dispatchEventImpl(e);
1663: }
1664:
1665:
1675: boolean eventTypeEnabled(int eventId)
1676: {
1677: if(eventId <= ContainerEvent.CONTAINER_LAST
1678: && eventId >= ContainerEvent.CONTAINER_FIRST)
1679: return containerListener != null
1680: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0;
1681: else
1682: return super.eventTypeEnabled(eventId);
1683: }
1684:
1685:
1686: Component findNextFocusComponent(Component child)
1687: {
1688: synchronized (getTreeLock ())
1689: {
1690: int start, end;
1691: if (child != null)
1692: {
1693: for (start = 0; start < ncomponents; ++start)
1694: {
1695: if (component[start] == child)
1696: break;
1697: }
1698: end = start;
1699:
1700: if (end == 0)
1701: end = ncomponents;
1702: ++start;
1703: }
1704: else
1705: {
1706: start = 0;
1707: end = ncomponents;
1708: }
1709:
1710: for (int j = start; j != end; ++j)
1711: {
1712: if (j >= ncomponents)
1713: {
1714:
1715:
1716:
1717:
1718: if (parent != null)
1719: return parent.findNextFocusComponent(this);
1720: j -= ncomponents;
1721: }
1722: if (component[j] instanceof Container)
1723: {
1724: Component c = component[j];
1725: c = c.findNextFocusComponent(null);
1726: if (c != null)
1727: return c;
1728: }
1729: else if (component[j].isFocusTraversable())
1730: return component[j];
1731: }
1732:
1733: return null;
1734: }
1735: }
1736:
1737: private void addNotifyContainerChildren()
1738: {
1739: synchronized (getTreeLock ())
1740: {
1741: for (int i = ncomponents; --i >= 0; )
1742: {
1743: component[i].addNotify();
1744: if (component[i].isLightweight ())
1745: {
1746:
1747:
1748:
1749: if (!this.isLightweight() && dispatcher == null)
1750: dispatcher = new LightweightDispatcher (this);
1751:
1752: if (dispatcher != null)
1753: dispatcher.enableEvents(component[i].eventMask);
1754:
1755: enableEvents(component[i].eventMask);
1756: if (peer != null && !isLightweight ())
1757: enableEvents (AWTEvent.PAINT_EVENT_MASK);
1758: }
1759: }
1760: }
1761: }
1762:
1763:
1778: private void readObject (ObjectInputStream s)
1779: throws ClassNotFoundException, IOException
1780: {
1781: s.defaultReadObject ();
1782: String key = (String) s.readObject ();
1783: while (key != null)
1784: {
1785: Object object = s.readObject ();
1786: if ("containerL".equals (key))
1787: addContainerListener((ContainerListener) object);
1788:
1789: else if ("focusTraversalPolicy".equals (key))
1790: setFocusTraversalPolicy ((FocusTraversalPolicy) object);
1791:
1792: key = (String) s.readObject();
1793: }
1794: }
1795:
1796:
1808: private void writeObject (ObjectOutputStream s) throws IOException
1809: {
1810: s.defaultWriteObject ();
1811: AWTEventMulticaster.save (s, "containerL", containerListener);
1812: if (focusTraversalPolicy instanceof Serializable)
1813: s.writeObject (focusTraversalPolicy);
1814: else
1815: s.writeObject (null);
1816: }
1817:
1818:
1819:
1820:
1823:
1824: abstract static class GfxVisitor
1825: {
1826: public abstract void visit(Component c, Graphics gfx);
1827: }
1828:
1829: static class GfxPaintVisitor extends GfxVisitor
1830: {
1831: public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
1832:
1833: public void visit(Component c, Graphics gfx)
1834: {
1835: c.paint(gfx);
1836: }
1837: }
1838:
1839: static class GfxPrintVisitor extends GfxVisitor
1840: {
1841: public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
1842:
1843: public void visit(Component c, Graphics gfx)
1844: {
1845: c.print(gfx);
1846: }
1847: }
1848:
1849: static class GfxPaintAllVisitor extends GfxVisitor
1850: {
1851: public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
1852:
1853: public void visit(Component c, Graphics gfx)
1854: {
1855: c.paintAll(gfx);
1856: }
1857: }
1858:
1859: static class GfxPrintAllVisitor extends GfxVisitor
1860: {
1861: public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
1862:
1863: public void visit(Component c, Graphics gfx)
1864: {
1865: c.printAll(gfx);
1866: }
1867: }
1868:
1869:
1876: protected class AccessibleAWTContainer extends AccessibleAWTComponent
1877: {
1878:
1881: private static final long serialVersionUID = 5081320404842566097L;
1882:
1883:
1888: protected ContainerListener accessibleContainerHandler
1889: = new AccessibleContainerHandler();
1890:
1891:
1894: protected AccessibleAWTContainer()
1895: {
1896: Container.this.addContainerListener(accessibleContainerHandler);
1897: }
1898:
1899:
1905: public int getAccessibleChildrenCount()
1906: {
1907: synchronized (getTreeLock ())
1908: {
1909: int count = 0;
1910: int i = component == null ? 0 : component.length;
1911: while (--i >= 0)
1912: if (component[i] instanceof Accessible)
1913: count++;
1914: return count;
1915: }
1916: }
1917:
1918:
1924: public Accessible getAccessibleChild(int i)
1925: {
1926: synchronized (getTreeLock ())
1927: {
1928: if (component == null)
1929: return null;
1930: int index = -1;
1931: while (i >= 0 && ++index < component.length)
1932: if (component[index] instanceof Accessible)
1933: i--;
1934: if (i < 0)
1935: return (Accessible) component[index];
1936: return null;
1937: }
1938: }
1939:
1940:
1950: public Accessible getAccessibleAt(Point p)
1951: {
1952: Component c = getComponentAt(p.x, p.y);
1953: return c != Container.this && c instanceof Accessible ? (Accessible) c
1954: : null;
1955: }
1956:
1957:
1965: protected class AccessibleContainerHandler implements ContainerListener
1966: {
1967:
1970: protected AccessibleContainerHandler()
1971: {
1972:
1973: }
1974:
1975:
1981: public void componentAdded(ContainerEvent e)
1982: {
1983: AccessibleAWTContainer.this.firePropertyChange
1984: (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
1985: }
1986:
1987:
1993: public void componentRemoved(ContainerEvent e)
1994: {
1995: AccessibleAWTContainer.this.firePropertyChange
1996: (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
1997: }
1998: }
1999: }
2000: }
2001:
2002:
2008: class LightweightDispatcher implements Serializable
2009: {
2010: private static final long serialVersionUID = 5184291520170872969L;
2011: private Container nativeContainer;
2012: private Cursor nativeCursor;
2013: private long eventMask;
2014:
2015: private transient Component pressedComponent;
2016: private transient Component lastComponentEntered;
2017: private transient int pressCount;
2018:
2019: LightweightDispatcher(Container c)
2020: {
2021: nativeContainer = c;
2022: }
2023:
2024: void enableEvents(long l)
2025: {
2026: eventMask |= l;
2027: }
2028:
2029:
2040: Component getDeepestComponentForMouseEventAt(Component parent, int x, int y)
2041: {
2042: if (parent == null || (! parent.contains(x, y)))
2043: return null;
2044:
2045: if (! (parent instanceof Container))
2046: return parent;
2047:
2048: Container c = (Container) parent;
2049: return c.findComponentForMouseEventAt(x, y);
2050: }
2051:
2052: Component acquireComponentForMouseEvent(MouseEvent me)
2053: {
2054: int x = me.getX ();
2055: int y = me.getY ();
2056:
2057: Component mouseEventTarget = null;
2058:
2059: Component parent = nativeContainer;
2060: Component candidate = null;
2061: Point p = me.getPoint();
2062: while (candidate == null && parent != null)
2063: {
2064: candidate = getDeepestComponentForMouseEventAt(parent, p.x, p.y);
2065: if (candidate == null || (candidate.eventMask & me.getID()) == 0)
2066: {
2067: candidate = null;
2068: p = AWTUtilities.convertPoint(parent, p.x, p.y, parent.parent);
2069: parent = parent.parent;
2070: }
2071: }
2072:
2073:
2074:
2075:
2076: if (candidate == nativeContainer)
2077: candidate = null;
2078:
2079:
2080: if (lastComponentEntered != null
2081: && lastComponentEntered.isShowing()
2082: && lastComponentEntered != candidate)
2083: {
2084:
2085:
2086: if (AWTUtilities.isDescendingFrom(lastComponentEntered,
2087: nativeContainer))
2088: {
2089: Point tp = AWTUtilities.convertPoint(nativeContainer,
2090: x, y, lastComponentEntered);
2091: MouseEvent exited = new MouseEvent (lastComponentEntered,
2092: MouseEvent.MOUSE_EXITED,
2093: me.getWhen (),
2094: me.getModifiersEx (),
2095: tp.x, tp.y,
2096: me.getClickCount (),
2097: me.isPopupTrigger (),
2098: me.getButton ());
2099: lastComponentEntered.dispatchEvent (exited);
2100: }
2101: lastComponentEntered = null;
2102: }
2103:
2104:
2105: if (candidate != null)
2106: {
2107: mouseEventTarget = candidate;
2108: if (candidate.isLightweight()
2109: && candidate.isShowing()
2110: && candidate != nativeContainer
2111: && candidate != lastComponentEntered)
2112: {
2113: lastComponentEntered = mouseEventTarget;
2114: Point cp = AWTUtilities.convertPoint(nativeContainer,
2115: x, y, lastComponentEntered);
2116: MouseEvent entered = new MouseEvent (lastComponentEntered,
2117: MouseEvent.MOUSE_ENTERED,
2118: me.getWhen (),
2119: me.getModifiersEx (),
2120: cp.x, cp.y,
2121: me.getClickCount (),
2122: me.isPopupTrigger (),
2123: me.getButton ());
2124: lastComponentEntered.dispatchEvent (entered);
2125: }
2126: }
2127:
2128:
2129:
2130: int modifiers = me.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK
2131: | MouseEvent.BUTTON2_DOWN_MASK
2132: | MouseEvent.BUTTON3_DOWN_MASK);
2133: switch(me.getButton())
2134: {
2135: case MouseEvent.BUTTON1:
2136: modifiers &= ~MouseEvent.BUTTON1_DOWN_MASK;
2137: break;
2138: case MouseEvent.BUTTON2:
2139: modifiers &= ~MouseEvent.BUTTON2_DOWN_MASK;
2140: break;
2141: case MouseEvent.BUTTON3:
2142: modifiers &= ~MouseEvent.BUTTON3_DOWN_MASK;
2143: break;
2144: }
2145:
2146: if (me.getID() == MouseEvent.MOUSE_RELEASED
2147: || me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
2148: || me.getID() == MouseEvent.MOUSE_DRAGGED)
2149: {
2150:
2151:
2152:
2153:
2154:
2155:
2156:
2157:
2158:
2159:
2160:
2161: if (AWTUtilities.isDescendingFrom(pressedComponent, nativeContainer))
2162: mouseEventTarget = pressedComponent;
2163: }
2164: else if (me.getID() == MouseEvent.MOUSE_CLICKED)
2165: {
2166:
2167:
2168: if (candidate != pressedComponent)
2169: {
2170: mouseEventTarget = null;
2171: pressCount = 0;
2172: }
2173: else if (pressCount == 0)
2174: pressedComponent = null;
2175: }
2176: return mouseEventTarget;
2177: }
2178:
2179: boolean handleEvent(AWTEvent e)
2180: {
2181: if (e instanceof MouseEvent)
2182: {
2183: MouseEvent me = (MouseEvent) e;
2184:
2185:
2186:
2187: Component mouseEventTarget = acquireComponentForMouseEvent(me);
2188:
2189:
2190: if (mouseEventTarget != null
2191: && mouseEventTarget.isShowing()
2192: && e.getID() != MouseEvent.MOUSE_ENTERED
2193: && e.getID() != MouseEvent.MOUSE_EXITED)
2194: {
2195: switch (e.getID())
2196: {
2197: case MouseEvent.MOUSE_PRESSED:
2198: if (pressCount++ == 0)
2199: pressedComponent = mouseEventTarget;
2200: break;
2201: case MouseEvent.MOUSE_RELEASED:
2202:
2203:
2204:
2205: if (--pressCount == 0
2206: && mouseEventTarget != pressedComponent)
2207: {
2208: pressedComponent = null;
2209: pressCount = 0;
2210: }
2211: break;
2212: }
2213:
2214: MouseEvent newEvt =
2215: AWTUtilities.convertMouseEvent(nativeContainer, me,
2216: mouseEventTarget);
2217: mouseEventTarget.dispatchEvent(newEvt);
2218:
2219: if (newEvt.isConsumed())
2220: e.consume();
2221: }
2222: }
2223:
2224: return e.isConsumed();
2225: }
2226: }