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: repaint();
455: }
456: }
457: }
458:
459:
464: public void remove(Component comp)
465: {
466: synchronized (getTreeLock ())
467: {
468: for (int i = 0; i < ncomponents; ++i)
469: {
470: if (component[i] == comp)
471: {
472: remove(i);
473: break;
474: }
475: }
476: }
477: }
478:
479:
482: public void removeAll()
483: {
484: synchronized (getTreeLock ())
485: {
486: while (ncomponents > 0)
487: remove(0);
488: }
489: }
490:
491:
496: public LayoutManager getLayout()
497: {
498: return layoutMgr;
499: }
500:
501:
507: public void setLayout(LayoutManager mgr)
508: {
509: layoutMgr = mgr;
510: invalidate();
511: }
512:
513:
516: public void doLayout()
517: {
518: layout ();
519: }
520:
521:
526: public void layout()
527: {
528: if (layoutMgr != null)
529: layoutMgr.layoutContainer (this);
530: }
531:
532:
536: public void invalidate()
537: {
538: super.invalidate();
539: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
540: {
541: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
542: lm2.invalidateLayout(this);
543: }
544: }
545:
546:
549: public void validate()
550: {
551: synchronized (getTreeLock ())
552: {
553: if (! isValid() && peer != null)
554: {
555: validateTree();
556: }
557: }
558: }
559:
560:
563: void invalidateTree()
564: {
565: super.invalidate();
566: for (int i = 0; i < ncomponents; i++)
567: {
568: Component comp = component[i];
569: comp.invalidate();
570: if (comp instanceof Container)
571: ((Container) comp).invalidateTree();
572: }
573:
574: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
575: {
576: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
577: lm2.invalidateLayout(this);
578: }
579: }
580:
581:
585: protected void validateTree()
586: {
587: if (valid)
588: return;
589:
590: ContainerPeer cPeer = null;
591: if (peer != null && ! (peer instanceof LightweightPeer))
592: {
593: cPeer = (ContainerPeer) peer;
594: cPeer.beginValidate();
595: }
596:
597: for (int i = 0; i < ncomponents; ++i)
598: {
599: Component comp = component[i];
600:
601: if (comp.getPeer () == null)
602: comp.addNotify();
603: }
604:
605: doLayout ();
606: for (int i = 0; i < ncomponents; ++i)
607: {
608: Component comp = component[i];
609:
610: if (! comp.isValid())
611: {
612: if (comp instanceof Container)
613: {
614: ((Container) comp).validateTree();
615: }
616: else
617: {
618: component[i].validate();
619: }
620: }
621: }
622:
623:
626: valid = true;
627:
628: if (cPeer != null)
629: cPeer.endValidate();
630: }
631:
632: public void setFont(Font f)
633: {
634: if( (f != null && (font == null || !font.equals(f)))
635: || f == null)
636: {
637: super.setFont(f);
638:
639:
640:
641: invalidateTree();
642: }
643: }
644:
645:
650: public Dimension getPreferredSize()
651: {
652: return preferredSize ();
653: }
654:
655:
662: public Dimension preferredSize()
663: {
664: synchronized(treeLock)
665: {
666: if(valid && prefSize != null)
667: return new Dimension(prefSize);
668: LayoutManager layout = getLayout();
669: if (layout != null)
670: {
671: Dimension layoutSize = layout.preferredLayoutSize(this);
672: if(valid)
673: prefSize = layoutSize;
674: return new Dimension(layoutSize);
675: }
676: else
677: return super.preferredSize ();
678: }
679: }
680:
681:
686: public Dimension getMinimumSize()
687: {
688: return minimumSize ();
689: }
690:
691:
698: public Dimension minimumSize()
699: {
700: if(valid && minSize != null)
701: return new Dimension(minSize);
702:
703: LayoutManager layout = getLayout();
704: if (layout != null)
705: {
706: minSize = layout.minimumLayoutSize (this);
707: return minSize;
708: }
709: else
710: return super.minimumSize ();
711: }
712:
713:
718: public Dimension getMaximumSize()
719: {
720: if (valid && maxSize != null)
721: return new Dimension(maxSize);
722:
723: LayoutManager layout = getLayout();
724: if (layout != null && layout instanceof LayoutManager2)
725: {
726: LayoutManager2 lm2 = (LayoutManager2) layout;
727: maxSize = lm2.maximumLayoutSize(this);
728: return maxSize;
729: }
730: else
731: return super.getMaximumSize();
732: }
733:
734:
741: public float getAlignmentX()
742: {
743: LayoutManager layout = getLayout();
744: float alignmentX = 0.0F;
745: if (layout != null && layout instanceof LayoutManager2)
746: {
747: LayoutManager2 lm2 = (LayoutManager2) layout;
748: alignmentX = lm2.getLayoutAlignmentX(this);
749: }
750: else
751: alignmentX = super.getAlignmentX();
752: return alignmentX;
753: }
754:
755:
762: public float getAlignmentY()
763: {
764: LayoutManager layout = getLayout();
765: float alignmentY = 0.0F;
766: if (layout != null && layout instanceof LayoutManager2)
767: {
768: LayoutManager2 lm2 = (LayoutManager2) layout;
769: alignmentY = lm2.getLayoutAlignmentY(this);
770: }
771: else
772: alignmentY = super.getAlignmentY();
773: return alignmentY;
774: }
775:
776:
785: public void paint(Graphics g)
786: {
787: if (!isShowing())
788: return;
789:
790:
791:
792: visitChildren(g, GfxPaintVisitor.INSTANCE, false);
793: }
794:
795:
812: public void update(Graphics g)
813: {
814:
815:
816:
817:
818:
819:
820:
821:
822: ComponentPeer p = peer;
823: if (p != null && !(p instanceof LightweightPeer))
824: g.clearRect(0, 0, getWidth(), getHeight());
825:
826: paint(g);
827: }
828:
829:
838: public void print(Graphics g)
839: {
840: super.print(g);
841: visitChildren(g, GfxPrintVisitor.INSTANCE, true);
842: }
843:
844:
849: public void paintComponents(Graphics g)
850: {
851: paint(g);
852: visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
853: }
854:
855:
860: public void printComponents(Graphics g)
861: {
862: super.paint(g);
863: visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
864: }
865:
866:
872: public synchronized void addContainerListener(ContainerListener listener)
873: {
874: containerListener = AWTEventMulticaster.add(containerListener, listener);
875: }
876:
877:
883: public synchronized void removeContainerListener(ContainerListener listener)
884: {
885: containerListener = AWTEventMulticaster.remove(containerListener, listener);
886: }
887:
888:
891: public synchronized ContainerListener[] getContainerListeners()
892: {
893: return (ContainerListener[])
894: AWTEventMulticaster.getListeners(containerListener,
895: ContainerListener.class);
896: }
897:
898:
908: public EventListener[] getListeners(Class listenerType)
909: {
910: if (listenerType == ContainerListener.class)
911: return getContainerListeners();
912: return super.getListeners(listenerType);
913: }
914:
915:
923: protected void processEvent(AWTEvent e)
924: {
925: if (e instanceof ContainerEvent)
926: processContainerEvent((ContainerEvent) e);
927: else
928: super.processEvent(e);
929: }
930:
931:
937: protected void processContainerEvent(ContainerEvent e)
938: {
939: if (containerListener == null)
940: return;
941: switch (e.id)
942: {
943: case ContainerEvent.COMPONENT_ADDED:
944: containerListener.componentAdded(e);
945: break;
946:
947: case ContainerEvent.COMPONENT_REMOVED:
948: containerListener.componentRemoved(e);
949: break;
950: }
951: }
952:
953:
960: public void deliverEvent(Event e)
961: {
962: if (!handleEvent (e))
963: {
964: synchronized (getTreeLock ())
965: {
966: Component parent = getParent ();
967:
968: if (parent != null)
969: parent.deliverEvent (e);
970: }
971: }
972: }
973:
974:
988: public Component getComponentAt(int x, int y)
989: {
990: return locate (x, y);
991: }
992:
993:
1009: public Component locate(int x, int y)
1010: {
1011: synchronized (getTreeLock ())
1012: {
1013: if (!contains (x, y))
1014: return null;
1015: for (int i = 0; i < ncomponents; ++i)
1016: {
1017:
1018: if (!component[i].isVisible ())
1019: continue;
1020:
1021: int x2 = x - component[i].x;
1022: int y2 = y - component[i].y;
1023: if (component[i].contains (x2, y2))
1024: return component[i];
1025: }
1026: return this;
1027: }
1028: }
1029:
1030:
1042: public Component getComponentAt(Point p)
1043: {
1044: return getComponentAt (p.x, p.y);
1045: }
1046:
1047: public Component findComponentAt(int x, int y)
1048: {
1049: synchronized (getTreeLock ())
1050: {
1051: if (! contains(x, y))
1052: return null;
1053:
1054: for (int i = 0; i < ncomponents; ++i)
1055: {
1056:
1057: if (!component[i].isVisible())
1058: continue;
1059:
1060: int x2 = x - component[i].x;
1061: int y2 = y - component[i].y;
1062:
1063:
1064: if (component[i] instanceof Container)
1065: {
1066: Container k = (Container) component[i];
1067: Component r = k.findComponentAt(x2, y2);
1068: if (r != null)
1069: return r;
1070: }
1071: else if (component[i].contains(x2, y2))
1072: return component[i];
1073: }
1074:
1075: return this;
1076: }
1077: }
1078:
1079:
1091: Component findComponentForMouseEventAt(int x, int y)
1092: {
1093: synchronized (getTreeLock())
1094: {
1095: if (!contains(x, y))
1096: return null;
1097:
1098: for (int i = 0; i < ncomponents; ++i)
1099: {
1100:
1101: if (!component[i].isVisible())
1102: continue;
1103:
1104: int x2 = x - component[i].x;
1105: int y2 = y - component[i].y;
1106:
1107:
1108: if (component[i] instanceof Container)
1109: {
1110: Container k = (Container) component[i];
1111: Component r = k.findComponentForMouseEventAt(x2, y2);
1112: if (r != null)
1113: return r;
1114: }
1115: else if (component[i].contains(x2, y2))
1116: return component[i];
1117: }
1118:
1119:
1120: if (this.getMouseListeners().length == 0)
1121: return null;
1122: return this;
1123: }
1124: }
1125:
1126: public Component findComponentAt(Point p)
1127: {
1128: return findComponentAt(p.x, p.y);
1129: }
1130:
1131:
1136: public void addNotify()
1137: {
1138: super.addNotify();
1139: addNotifyContainerChildren();
1140: }
1141:
1142:
1147: public void removeNotify()
1148: {
1149: synchronized (getTreeLock ())
1150: {
1151: for (int i = 0; i < ncomponents; ++i)
1152: component[i].removeNotify();
1153: super.removeNotify();
1154: }
1155: }
1156:
1157:
1166: public boolean isAncestorOf(Component comp)
1167: {
1168: synchronized (getTreeLock ())
1169: {
1170: while (true)
1171: {
1172: if (comp == null)
1173: return false;
1174: if (comp == this)
1175: return true;
1176: comp = comp.getParent();
1177: }
1178: }
1179: }
1180:
1181:
1187: protected String paramString()
1188: {
1189: if (layoutMgr == null)
1190: return super.paramString();
1191:
1192: StringBuffer sb = new StringBuffer();
1193: sb.append(super.paramString());
1194: sb.append(",layout=");
1195: sb.append(layoutMgr.getClass().getName());
1196: return sb.toString();
1197: }
1198:
1199:
1206: public void list(PrintStream out, int indent)
1207: {
1208: synchronized (getTreeLock ())
1209: {
1210: super.list(out, indent);
1211: for (int i = 0; i < ncomponents; ++i)
1212: component[i].list(out, indent + 2);
1213: }
1214: }
1215:
1216:
1223: public void list(PrintWriter out, int indent)
1224: {
1225: synchronized (getTreeLock ())
1226: {
1227: super.list(out, indent);
1228: for (int i = 0; i < ncomponents; ++i)
1229: component[i].list(out, indent + 2);
1230: }
1231: }
1232:
1233:
1249: public void setFocusTraversalKeys(int id, Set keystrokes)
1250: {
1251: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1252: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1253: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1254: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1255: throw new IllegalArgumentException ();
1256:
1257: if (keystrokes == null)
1258: {
1259: Container parent = getParent ();
1260:
1261: while (parent != null)
1262: {
1263: if (parent.areFocusTraversalKeysSet (id))
1264: {
1265: keystrokes = parent.getFocusTraversalKeys (id);
1266: break;
1267: }
1268: parent = parent.getParent ();
1269: }
1270:
1271: if (keystrokes == null)
1272: keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
1273: getDefaultFocusTraversalKeys (id);
1274: }
1275:
1276: Set sa;
1277: Set sb;
1278: Set sc;
1279: String name;
1280: switch (id)
1281: {
1282: case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
1283: sa = getFocusTraversalKeys
1284: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1285: sb = getFocusTraversalKeys
1286: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1287: sc = getFocusTraversalKeys
1288: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1289: name = "forwardFocusTraversalKeys";
1290: break;
1291: case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
1292: sa = getFocusTraversalKeys
1293: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1294: sb = getFocusTraversalKeys
1295: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1296: sc = getFocusTraversalKeys
1297: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1298: name = "backwardFocusTraversalKeys";
1299: break;
1300: case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
1301: sa = getFocusTraversalKeys
1302: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1303: sb = getFocusTraversalKeys
1304: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1305: sc = getFocusTraversalKeys
1306: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1307: name = "upCycleFocusTraversalKeys";
1308: break;
1309: case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
1310: sa = getFocusTraversalKeys
1311: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1312: sb = getFocusTraversalKeys
1313: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1314: sc = getFocusTraversalKeys
1315: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1316: name = "downCycleFocusTraversalKeys";
1317: break;
1318: default:
1319: throw new IllegalArgumentException ();
1320: }
1321:
1322: int i = keystrokes.size ();
1323: Iterator iter = keystrokes.iterator ();
1324:
1325: while (--i >= 0)
1326: {
1327: Object o = iter.next ();
1328: if (!(o instanceof AWTKeyStroke)
1329: || sa.contains (o) || sb.contains (o) || sc.contains (o)
1330: || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
1331: throw new IllegalArgumentException ();
1332: }
1333:
1334: if (focusTraversalKeys == null)
1335: focusTraversalKeys = new Set[4];
1336:
1337: keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
1338: firePropertyChange (name, focusTraversalKeys[id], keystrokes);
1339:
1340: focusTraversalKeys[id] = keystrokes;
1341: }
1342:
1343:
1355: public Set getFocusTraversalKeys (int id)
1356: {
1357: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1358: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1359: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1360: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1361: throw new IllegalArgumentException ();
1362:
1363: Set s = null;
1364:
1365: if (focusTraversalKeys != null)
1366: s = focusTraversalKeys[id];
1367:
1368: if (s == null && parent != null)
1369: s = parent.getFocusTraversalKeys (id);
1370:
1371: return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
1372: .getDefaultFocusTraversalKeys(id)) : s;
1373: }
1374:
1375:
1389: public boolean areFocusTraversalKeysSet (int id)
1390: {
1391: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1392: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1393: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1394: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1395: throw new IllegalArgumentException ();
1396:
1397: return focusTraversalKeys != null && focusTraversalKeys[id] != null;
1398: }
1399:
1400:
1415: public boolean isFocusCycleRoot (Container c)
1416: {
1417: if (this == c
1418: && isFocusCycleRoot ())
1419: return true;
1420:
1421: Container ancestor = getFocusCycleRootAncestor ();
1422:
1423: if (c == ancestor)
1424: return true;
1425:
1426: return false;
1427: }
1428:
1429:
1441: public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
1442: {
1443: focusTraversalPolicy = policy;
1444: }
1445:
1446:
1457: public FocusTraversalPolicy getFocusTraversalPolicy ()
1458: {
1459: if (!isFocusCycleRoot ())
1460: return null;
1461:
1462: if (focusTraversalPolicy == null)
1463: {
1464: Container ancestor = getFocusCycleRootAncestor ();
1465:
1466: if (ancestor != this)
1467: return ancestor.getFocusTraversalPolicy ();
1468: else
1469: {
1470: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1471:
1472: return manager.getDefaultFocusTraversalPolicy ();
1473: }
1474: }
1475: else
1476: return focusTraversalPolicy;
1477: }
1478:
1479:
1487: public boolean isFocusTraversalPolicySet ()
1488: {
1489: return focusTraversalPolicy == null;
1490: }
1491:
1492:
1508: public void setFocusCycleRoot (boolean focusCycleRoot)
1509: {
1510: this.focusCycleRoot = focusCycleRoot;
1511: }
1512:
1513:
1520: public boolean isFocusCycleRoot ()
1521: {
1522: return focusCycleRoot;
1523: }
1524:
1525:
1534: public void transferFocusDownCycle ()
1535: {
1536: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1537:
1538: manager.downFocusCycle (this);
1539: }
1540:
1541:
1549: public void applyComponentOrientation (ComponentOrientation orientation)
1550: {
1551: if (orientation == null)
1552: throw new NullPointerException ();
1553: }
1554:
1555: public void addPropertyChangeListener (PropertyChangeListener listener)
1556: {
1557: if (listener == null)
1558: return;
1559:
1560: if (changeSupport == null)
1561: changeSupport = new PropertyChangeSupport (this);
1562:
1563: changeSupport.addPropertyChangeListener (listener);
1564: }
1565:
1566: public void addPropertyChangeListener (String name,
1567: PropertyChangeListener listener)
1568: {
1569: if (listener == null)
1570: return;
1571:
1572: if (changeSupport == null)
1573: changeSupport = new PropertyChangeSupport (this);
1574:
1575: changeSupport.addPropertyChangeListener (name, listener);
1576: }
1577:
1578:
1579:
1580:
1594: private void visitChildren(Graphics gfx, GfxVisitor visitor,
1595: boolean lightweightOnly)
1596: {
1597: synchronized (getTreeLock ())
1598: {
1599: for (int i = ncomponents - 1; i >= 0; --i)
1600: {
1601: Component comp = component[i];
1602: boolean applicable = comp.isVisible()
1603: && (comp.isLightweight() || !lightweightOnly);
1604:
1605: if (applicable)
1606: visitChild(gfx, visitor, comp);
1607: }
1608: }
1609: }
1610:
1611:
1624: private void visitChild(Graphics gfx, GfxVisitor visitor,
1625: Component comp)
1626: {
1627: Rectangle bounds = comp.getBounds();
1628: Rectangle oldClip = gfx.getClipBounds();
1629: if (oldClip == null)
1630: oldClip = bounds;
1631:
1632: Rectangle clip = oldClip.intersection(bounds);
1633:
1634: if (clip.isEmpty()) return;
1635:
1636: boolean clipped = false;
1637: boolean translated = false;
1638: try
1639: {
1640: gfx.setClip(clip.x, clip.y, clip.width, clip.height);
1641: clipped = true;
1642: gfx.translate(bounds.x, bounds.y);
1643: translated = true;
1644: visitor.visit(comp, gfx);
1645: }
1646: finally
1647: {
1648: if (translated)
1649: gfx.translate (-bounds.x, -bounds.y);
1650: if (clipped)
1651: gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
1652: }
1653: }
1654:
1655: void dispatchEventImpl(AWTEvent e)
1656: {
1657:
1658: if (dispatcher != null && dispatcher.handleEvent (e))
1659: return;
1660:
1661: if ((e.id <= ContainerEvent.CONTAINER_LAST
1662: && e.id >= ContainerEvent.CONTAINER_FIRST)
1663: && (containerListener != null
1664: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
1665: processEvent(e);
1666: else
1667: super.dispatchEventImpl(e);
1668: }
1669:
1670:
1680: boolean eventTypeEnabled(int eventId)
1681: {
1682: if(eventId <= ContainerEvent.CONTAINER_LAST
1683: && eventId >= ContainerEvent.CONTAINER_FIRST)
1684: return containerListener != null
1685: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0;
1686: else
1687: return super.eventTypeEnabled(eventId);
1688: }
1689:
1690:
1691: Component findNextFocusComponent(Component child)
1692: {
1693: synchronized (getTreeLock ())
1694: {
1695: int start, end;
1696: if (child != null)
1697: {
1698: for (start = 0; start < ncomponents; ++start)
1699: {
1700: if (component[start] == child)
1701: break;
1702: }
1703: end = start;
1704:
1705: if (end == 0)
1706: end = ncomponents;
1707: ++start;
1708: }
1709: else
1710: {
1711: start = 0;
1712: end = ncomponents;
1713: }
1714:
1715: for (int j = start; j != end; ++j)
1716: {
1717: if (j >= ncomponents)
1718: {
1719:
1720:
1721:
1722:
1723: if (parent != null)
1724: return parent.findNextFocusComponent(this);
1725: j -= ncomponents;
1726: }
1727: if (component[j] instanceof Container)
1728: {
1729: Component c = component[j];
1730: c = c.findNextFocusComponent(null);
1731: if (c != null)
1732: return c;
1733: }
1734: else if (component[j].isFocusTraversable())
1735: return component[j];
1736: }
1737:
1738: return null;
1739: }
1740: }
1741:
1742: private void addNotifyContainerChildren()
1743: {
1744: synchronized (getTreeLock ())
1745: {
1746: for (int i = ncomponents; --i >= 0; )
1747: {
1748: component[i].addNotify();
1749: if (component[i].isLightweight ())
1750: {
1751:
1752:
1753:
1754: if (!this.isLightweight() && dispatcher == null)
1755: dispatcher = new LightweightDispatcher (this);
1756:
1757: if (dispatcher != null)
1758: dispatcher.enableEvents(component[i].eventMask);
1759:
1760: enableEvents(component[i].eventMask);
1761: if (peer != null && !isLightweight ())
1762: enableEvents (AWTEvent.PAINT_EVENT_MASK);
1763: }
1764: }
1765: }
1766: }
1767:
1768:
1783: private void readObject (ObjectInputStream s)
1784: throws ClassNotFoundException, IOException
1785: {
1786: s.defaultReadObject ();
1787: String key = (String) s.readObject ();
1788: while (key != null)
1789: {
1790: Object object = s.readObject ();
1791: if ("containerL".equals (key))
1792: addContainerListener((ContainerListener) object);
1793:
1794: else if ("focusTraversalPolicy".equals (key))
1795: setFocusTraversalPolicy ((FocusTraversalPolicy) object);
1796:
1797: key = (String) s.readObject();
1798: }
1799: }
1800:
1801:
1813: private void writeObject (ObjectOutputStream s) throws IOException
1814: {
1815: s.defaultWriteObject ();
1816: AWTEventMulticaster.save (s, "containerL", containerListener);
1817: if (focusTraversalPolicy instanceof Serializable)
1818: s.writeObject (focusTraversalPolicy);
1819: else
1820: s.writeObject (null);
1821: }
1822:
1823:
1824:
1825:
1828:
1829: abstract static class GfxVisitor
1830: {
1831: public abstract void visit(Component c, Graphics gfx);
1832: }
1833:
1834: static class GfxPaintVisitor extends GfxVisitor
1835: {
1836: public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
1837:
1838: public void visit(Component c, Graphics gfx)
1839: {
1840: c.paint(gfx);
1841: }
1842: }
1843:
1844: static class GfxPrintVisitor extends GfxVisitor
1845: {
1846: public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
1847:
1848: public void visit(Component c, Graphics gfx)
1849: {
1850: c.print(gfx);
1851: }
1852: }
1853:
1854: static class GfxPaintAllVisitor extends GfxVisitor
1855: {
1856: public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
1857:
1858: public void visit(Component c, Graphics gfx)
1859: {
1860: c.paintAll(gfx);
1861: }
1862: }
1863:
1864: static class GfxPrintAllVisitor extends GfxVisitor
1865: {
1866: public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
1867:
1868: public void visit(Component c, Graphics gfx)
1869: {
1870: c.printAll(gfx);
1871: }
1872: }
1873:
1874:
1881: protected class AccessibleAWTContainer extends AccessibleAWTComponent
1882: {
1883:
1886: private static final long serialVersionUID = 5081320404842566097L;
1887:
1888:
1893: protected ContainerListener accessibleContainerHandler
1894: = new AccessibleContainerHandler();
1895:
1896:
1899: protected AccessibleAWTContainer()
1900: {
1901: Container.this.addContainerListener(accessibleContainerHandler);
1902: }
1903:
1904:
1910: public int getAccessibleChildrenCount()
1911: {
1912: synchronized (getTreeLock ())
1913: {
1914: int count = 0;
1915: int i = component == null ? 0 : component.length;
1916: while (--i >= 0)
1917: if (component[i] instanceof Accessible)
1918: count++;
1919: return count;
1920: }
1921: }
1922:
1923:
1929: public Accessible getAccessibleChild(int i)
1930: {
1931: synchronized (getTreeLock ())
1932: {
1933: if (component == null)
1934: return null;
1935: int index = -1;
1936: while (i >= 0 && ++index < component.length)
1937: if (component[index] instanceof Accessible)
1938: i--;
1939: if (i < 0)
1940: return (Accessible) component[index];
1941: return null;
1942: }
1943: }
1944:
1945:
1955: public Accessible getAccessibleAt(Point p)
1956: {
1957: Component c = getComponentAt(p.x, p.y);
1958: return c != Container.this && c instanceof Accessible ? (Accessible) c
1959: : null;
1960: }
1961:
1962:
1970: protected class AccessibleContainerHandler implements ContainerListener
1971: {
1972:
1975: protected AccessibleContainerHandler()
1976: {
1977:
1978: }
1979:
1980:
1986: public void componentAdded(ContainerEvent e)
1987: {
1988: AccessibleAWTContainer.this.firePropertyChange
1989: (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
1990: }
1991:
1992:
1998: public void componentRemoved(ContainerEvent e)
1999: {
2000: AccessibleAWTContainer.this.firePropertyChange
2001: (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
2002: }
2003: }
2004: }
2005: }
2006:
2007:
2013: class LightweightDispatcher implements Serializable
2014: {
2015: private static final long serialVersionUID = 5184291520170872969L;
2016: private Container nativeContainer;
2017: private Cursor nativeCursor;
2018: private long eventMask;
2019:
2020: private transient Component pressedComponent;
2021: private transient Component lastComponentEntered;
2022: private transient int pressCount;
2023:
2024: LightweightDispatcher(Container c)
2025: {
2026: nativeContainer = c;
2027: }
2028:
2029: void enableEvents(long l)
2030: {
2031: eventMask |= l;
2032: }
2033:
2034:
2045: Component getDeepestComponentForMouseEventAt(Component parent, int x, int y)
2046: {
2047: if (parent == null || (! parent.contains(x, y)))
2048: return null;
2049:
2050: if (! (parent instanceof Container))
2051: return parent;
2052:
2053: Container c = (Container) parent;
2054: return c.findComponentForMouseEventAt(x, y);
2055: }
2056:
2057: Component acquireComponentForMouseEvent(MouseEvent me)
2058: {
2059: int x = me.getX ();
2060: int y = me.getY ();
2061:
2062: Component mouseEventTarget = null;
2063:
2064: Component parent = nativeContainer;
2065: Component candidate = null;
2066: Point p = me.getPoint();
2067: while (candidate == null && parent != null)
2068: {
2069: candidate = getDeepestComponentForMouseEventAt(parent, p.x, p.y);
2070: if (candidate == null || (candidate.eventMask & me.getID()) == 0)
2071: {
2072: candidate = null;
2073: p = AWTUtilities.convertPoint(parent, p.x, p.y, parent.parent);
2074: parent = parent.parent;
2075: }
2076: }
2077:
2078:
2079:
2080:
2081: if (candidate == nativeContainer)
2082: candidate = null;
2083:
2084:
2085: if (lastComponentEntered != null
2086: && lastComponentEntered.isShowing()
2087: && lastComponentEntered != candidate)
2088: {
2089:
2090:
2091: if (AWTUtilities.isDescendingFrom(lastComponentEntered,
2092: nativeContainer))
2093: {
2094: Point tp = AWTUtilities.convertPoint(nativeContainer,
2095: x, y, lastComponentEntered);
2096: MouseEvent exited = new MouseEvent (lastComponentEntered,
2097: MouseEvent.MOUSE_EXITED,
2098: me.getWhen (),
2099: me.getModifiersEx (),
2100: tp.x, tp.y,
2101: me.getClickCount (),
2102: me.isPopupTrigger (),
2103: me.getButton ());
2104: lastComponentEntered.dispatchEvent (exited);
2105: }
2106: lastComponentEntered = null;
2107: }
2108:
2109:
2110: if (candidate != null)
2111: {
2112: mouseEventTarget = candidate;
2113: if (candidate.isLightweight()
2114: && candidate.isShowing()
2115: && candidate != nativeContainer
2116: && candidate != lastComponentEntered)
2117: {
2118: lastComponentEntered = mouseEventTarget;
2119: Point cp = AWTUtilities.convertPoint(nativeContainer,
2120: x, y, lastComponentEntered);
2121: MouseEvent entered = new MouseEvent (lastComponentEntered,
2122: MouseEvent.MOUSE_ENTERED,
2123: me.getWhen (),
2124: me.getModifiersEx (),
2125: cp.x, cp.y,
2126: me.getClickCount (),
2127: me.isPopupTrigger (),
2128: me.getButton ());
2129: lastComponentEntered.dispatchEvent (entered);
2130: }
2131: }
2132:
2133:
2134:
2135: int modifiers = me.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK
2136: | MouseEvent.BUTTON2_DOWN_MASK
2137: | MouseEvent.BUTTON3_DOWN_MASK);
2138: switch(me.getButton())
2139: {
2140: case MouseEvent.BUTTON1:
2141: modifiers &= ~MouseEvent.BUTTON1_DOWN_MASK;
2142: break;
2143: case MouseEvent.BUTTON2:
2144: modifiers &= ~MouseEvent.BUTTON2_DOWN_MASK;
2145: break;
2146: case MouseEvent.BUTTON3:
2147: modifiers &= ~MouseEvent.BUTTON3_DOWN_MASK;
2148: break;
2149: }
2150:
2151: if (me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
2152: || me.getID() == MouseEvent.MOUSE_DRAGGED)
2153: {
2154:
2155:
2156:
2157:
2158:
2159:
2160: if (AWTUtilities.isDescendingFrom(pressedComponent, nativeContainer))
2161: mouseEventTarget = pressedComponent;
2162: }
2163: else if (me.getID() == MouseEvent.MOUSE_CLICKED)
2164: {
2165:
2166:
2167: if (candidate != pressedComponent)
2168: {
2169: mouseEventTarget = null;
2170: pressCount = 0;
2171: }
2172: else if (pressCount == 0)
2173: pressedComponent = null;
2174: }
2175: return mouseEventTarget;
2176: }
2177:
2178: boolean handleEvent(AWTEvent e)
2179: {
2180: if (e instanceof MouseEvent)
2181: {
2182: MouseEvent me = (MouseEvent) e;
2183:
2184:
2185:
2186: Component mouseEventTarget = acquireComponentForMouseEvent(me);
2187:
2188:
2189: if (mouseEventTarget != null
2190: && mouseEventTarget.isShowing()
2191: && e.getID() != MouseEvent.MOUSE_ENTERED
2192: && e.getID() != MouseEvent.MOUSE_EXITED)
2193: {
2194: switch (e.getID())
2195: {
2196: case MouseEvent.MOUSE_PRESSED:
2197: if (pressCount++ == 0)
2198: pressedComponent = mouseEventTarget;
2199: break;
2200: case MouseEvent.MOUSE_RELEASED:
2201:
2202:
2203:
2204: if (--pressCount == 0
2205: && mouseEventTarget != pressedComponent)
2206: {
2207: pressedComponent = null;
2208: pressCount = 0;
2209: }
2210: break;
2211: }
2212:
2213: MouseEvent newEvt =
2214: AWTUtilities.convertMouseEvent(nativeContainer, me,
2215: mouseEventTarget);
2216: mouseEventTarget.dispatchEvent(newEvt);
2217:
2218: if (newEvt.isConsumed())
2219: e.consume();
2220: }
2221: }
2222:
2223: return e.isConsumed();
2224: }
2225: }