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:
62: import ;
63:
64: import ;
65:
66:
78: public class Container extends Component
79: {
80:
83: private static final long serialVersionUID = 4613797578919906343L;
84:
85:
86: int ncomponents;
87: Component[] component;
88: LayoutManager layoutMgr;
89:
90: LightweightDispatcher dispatcher;
91:
92: Dimension maxSize;
93:
94:
97: boolean focusCycleRoot;
98:
99: int containerSerializedDataVersion;
100:
101:
102: transient ContainerListener containerListener;
103: transient PropertyChangeSupport changeSupport;
104:
105:
107: private FocusTraversalPolicy focusTraversalPolicy;
108:
109:
118: transient Set[] focusTraversalKeys;
119:
120:
123: public Container()
124: {
125: }
126:
127:
132: public int getComponentCount()
133: {
134: return countComponents ();
135: }
136:
137:
144: public int countComponents()
145: {
146: return ncomponents;
147: }
148:
149:
158: public Component getComponent(int n)
159: {
160: synchronized (getTreeLock ())
161: {
162: if (n < 0 || n >= ncomponents)
163: throw new ArrayIndexOutOfBoundsException("no such component");
164:
165: return component[n];
166: }
167: }
168:
169:
174: public Component[] getComponents()
175: {
176: synchronized (getTreeLock ())
177: {
178: Component[] result = new Component[ncomponents];
179:
180: if (ncomponents > 0)
181: System.arraycopy(component, 0, result, 0, ncomponents);
182:
183: return result;
184: }
185: }
186:
187:
190:
191: protected void swapComponents (int i, int j)
192: {
193: synchronized (getTreeLock ())
194: {
195: if (i < 0
196: || i >= component.length
197: || j < 0
198: || j >= component.length)
199: throw new ArrayIndexOutOfBoundsException ();
200: Component tmp = component[i];
201: component[i] = component[j];
202: component[j] = tmp;
203: }
204: }
205:
206:
212: public Insets getInsets()
213: {
214: return insets ();
215: }
216:
217:
224: public Insets insets()
225: {
226: if (peer == null)
227: return new Insets (0, 0, 0, 0);
228:
229: return ((ContainerPeer) peer).getInsets ();
230: }
231:
232:
240: public Component add(Component comp)
241: {
242: addImpl(comp, null, -1);
243: return comp;
244: }
245:
246:
258: public Component add(String name, Component comp)
259: {
260: addImpl(comp, name, -1);
261: return comp;
262: }
263:
264:
276: public Component add(Component comp, int index)
277: {
278: addImpl(comp, null, index);
279: return comp;
280: }
281:
282:
290: public void add(Component comp, Object constraints)
291: {
292: addImpl(comp, constraints, -1);
293: }
294:
295:
307: public void add(Component comp, Object constraints, int index)
308: {
309: addImpl(comp, constraints, index);
310: }
311:
312:
327: protected void addImpl(Component comp, Object constraints, int index)
328: {
329: synchronized (getTreeLock ())
330: {
331: if (index > ncomponents
332: || (index < 0 && index != -1)
333: || comp instanceof Window
334: || (comp instanceof Container
335: && ((Container) comp).isAncestorOf(this)))
336: throw new IllegalArgumentException();
337:
338:
339:
340: if (comp.parent != null)
341: comp.parent.remove(comp);
342: comp.parent = this;
343:
344: if (peer != null)
345: {
346:
347: comp.addNotify();
348:
349: if (comp.isLightweight ())
350: {
351: enableEvents (comp.eventMask);
352: if (!isLightweight ())
353: enableEvents (AWTEvent.PAINT_EVENT_MASK);
354: }
355: }
356:
357:
358: comp.invalidate();
359:
360: if (component == null)
361: component = new Component[4];
362:
363:
364:
365: if (ncomponents >= component.length)
366: {
367: int nl = component.length * 2;
368: Component[] c = new Component[nl];
369: System.arraycopy(component, 0, c, 0, ncomponents);
370: component = c;
371: }
372:
373: if (index == -1)
374: component[ncomponents++] = comp;
375: else
376: {
377: System.arraycopy(component, index, component, index + 1,
378: ncomponents - index);
379: component[index] = comp;
380: ++ncomponents;
381: }
382:
383:
384: if (layoutMgr != null)
385: {
386: if (layoutMgr instanceof LayoutManager2)
387: {
388: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
389: lm2.addLayoutComponent(comp, constraints);
390: }
391: else if (constraints instanceof String)
392: layoutMgr.addLayoutComponent((String) constraints, comp);
393: else
394: layoutMgr.addLayoutComponent(null, comp);
395: }
396:
397: if (isShowing ())
398: {
399:
400: ContainerEvent ce = new ContainerEvent(this,
401: ContainerEvent.COMPONENT_ADDED,
402: comp);
403: getToolkit().getSystemEventQueue().postEvent(ce);
404:
405:
406: repaint();
407: }
408: }
409: }
410:
411:
416: public void remove(int index)
417: {
418: synchronized (getTreeLock ())
419: {
420: Component r = component[index];
421:
422: r.removeNotify();
423:
424: System.arraycopy(component, index + 1, component, index,
425: ncomponents - index - 1);
426: component[--ncomponents] = null;
427:
428: invalidate();
429:
430: if (layoutMgr != null)
431: layoutMgr.removeLayoutComponent(r);
432:
433: r.parent = null;
434:
435: if (isShowing ())
436: {
437:
438: ContainerEvent ce = new ContainerEvent(this,
439: ContainerEvent.COMPONENT_REMOVED,
440: r);
441: getToolkit().getSystemEventQueue().postEvent(ce);
442:
443:
444: repaint();
445: }
446: }
447: }
448:
449:
454: public void remove(Component comp)
455: {
456: synchronized (getTreeLock ())
457: {
458: for (int i = 0; i < ncomponents; ++i)
459: {
460: if (component[i] == comp)
461: {
462: remove(i);
463: break;
464: }
465: }
466: }
467: }
468:
469:
472: public void removeAll()
473: {
474: synchronized (getTreeLock ())
475: {
476: while (ncomponents > 0)
477: remove(0);
478: }
479: }
480:
481:
486: public LayoutManager getLayout()
487: {
488: return layoutMgr;
489: }
490:
491:
497: public void setLayout(LayoutManager mgr)
498: {
499: layoutMgr = mgr;
500: invalidate();
501: }
502:
503:
506: public void doLayout()
507: {
508: layout ();
509: }
510:
511:
516: public void layout()
517: {
518: if (layoutMgr != null)
519: layoutMgr.layoutContainer (this);
520: }
521:
522:
526: public void invalidate()
527: {
528: super.invalidate();
529: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
530: {
531: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
532: lm2.invalidateLayout(this);
533: }
534: }
535:
536:
539: public void validate()
540: {
541: synchronized (getTreeLock ())
542: {
543: if (! isValid() && peer != null)
544: {
545: validateTree();
546: }
547: }
548: }
549:
550:
553: void invalidateTree()
554: {
555: super.invalidate();
556: for (int i = 0; i < ncomponents; i++)
557: {
558: Component comp = component[i];
559: comp.invalidate();
560: if (comp instanceof Container)
561: ((Container) comp).invalidateTree();
562: }
563:
564: if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
565: {
566: LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
567: lm2.invalidateLayout(this);
568: }
569: }
570:
571:
575: protected void validateTree()
576: {
577: if (valid)
578: return;
579:
580: ContainerPeer cPeer = null;
581: if (peer != null && ! (peer instanceof LightweightPeer))
582: {
583: cPeer = (ContainerPeer) peer;
584: cPeer.beginValidate();
585: }
586:
587: for (int i = 0; i < ncomponents; ++i)
588: {
589: Component comp = component[i];
590:
591: if (comp.getPeer () == null)
592: comp.addNotify();
593: }
594:
595: doLayout ();
596: for (int i = 0; i < ncomponents; ++i)
597: {
598: Component comp = component[i];
599:
600: if (! comp.isValid())
601: {
602: if (comp instanceof Container)
603: {
604: ((Container) comp).validateTree();
605: }
606: else
607: {
608: component[i].validate();
609: }
610: }
611: }
612:
613:
616: valid = true;
617:
618: if (cPeer != null)
619: cPeer.endValidate();
620: }
621:
622: public void setFont(Font f)
623: {
624: if( (f != null && (font == null || !font.equals(f)))
625: || f == null)
626: {
627: super.setFont(f);
628:
629:
630:
631: invalidateTree();
632: }
633: }
634:
635:
640: public Dimension getPreferredSize()
641: {
642: return preferredSize ();
643: }
644:
645:
652: public Dimension preferredSize()
653: {
654: synchronized(treeLock)
655: {
656: if(valid && prefSize != null)
657: return new Dimension(prefSize);
658: LayoutManager layout = getLayout();
659: if (layout != null)
660: {
661: Dimension layoutSize = layout.preferredLayoutSize(this);
662: if(valid)
663: prefSize = layoutSize;
664: return new Dimension(layoutSize);
665: }
666: else
667: return super.preferredSize ();
668: }
669: }
670:
671:
676: public Dimension getMinimumSize()
677: {
678: return minimumSize ();
679: }
680:
681:
688: public Dimension minimumSize()
689: {
690: if(valid && minSize != null)
691: return new Dimension(minSize);
692:
693: LayoutManager layout = getLayout();
694: if (layout != null)
695: {
696: minSize = layout.minimumLayoutSize (this);
697: return minSize;
698: }
699: else
700: return super.minimumSize ();
701: }
702:
703:
708: public Dimension getMaximumSize()
709: {
710: if (valid && maxSize != null)
711: return new Dimension(maxSize);
712:
713: LayoutManager layout = getLayout();
714: if (layout != null && layout instanceof LayoutManager2)
715: {
716: LayoutManager2 lm2 = (LayoutManager2) layout;
717: maxSize = lm2.maximumLayoutSize(this);
718: return maxSize;
719: }
720: else
721: return super.getMaximumSize();
722: }
723:
724:
731: public float getAlignmentX()
732: {
733: return super.getAlignmentX();
734: }
735:
736:
743: public float getAlignmentY()
744: {
745: return super.getAlignmentY();
746: }
747:
748:
757: public void paint(Graphics g)
758: {
759: if (!isShowing())
760: return;
761:
762:
763:
764: visitChildren(g, GfxPaintVisitor.INSTANCE, false);
765: }
766:
767:
784: public void update(Graphics g)
785: {
786:
787:
788:
789:
790:
791:
792:
793:
794: ComponentPeer p = peer;
795: if (p != null && !(p instanceof LightweightPeer))
796: g.clearRect(0, 0, getWidth(), getHeight());
797:
798: paint(g);
799: }
800:
801:
810: public void print(Graphics g)
811: {
812: super.print(g);
813: visitChildren(g, GfxPrintVisitor.INSTANCE, true);
814: }
815:
816:
821: public void paintComponents(Graphics g)
822: {
823: super.paint(g);
824: visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
825: }
826:
827:
832: public void printComponents(Graphics g)
833: {
834: super.paint(g);
835: visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
836: }
837:
838:
844: public synchronized void addContainerListener(ContainerListener listener)
845: {
846: containerListener = AWTEventMulticaster.add(containerListener, listener);
847: }
848:
849:
855: public synchronized void removeContainerListener(ContainerListener listener)
856: {
857: containerListener = AWTEventMulticaster.remove(containerListener, listener);
858: }
859:
860:
863: public synchronized ContainerListener[] getContainerListeners()
864: {
865: return (ContainerListener[])
866: AWTEventMulticaster.getListeners(containerListener,
867: ContainerListener.class);
868: }
869:
870:
880: public EventListener[] getListeners(Class listenerType)
881: {
882: if (listenerType == ContainerListener.class)
883: return getContainerListeners();
884: return super.getListeners(listenerType);
885: }
886:
887:
895: protected void processEvent(AWTEvent e)
896: {
897: if (e instanceof ContainerEvent)
898: processContainerEvent((ContainerEvent) e);
899: else
900: super.processEvent(e);
901: }
902:
903:
909: protected void processContainerEvent(ContainerEvent e)
910: {
911: if (containerListener == null)
912: return;
913: switch (e.id)
914: {
915: case ContainerEvent.COMPONENT_ADDED:
916: containerListener.componentAdded(e);
917: break;
918:
919: case ContainerEvent.COMPONENT_REMOVED:
920: containerListener.componentRemoved(e);
921: break;
922: }
923: }
924:
925:
932: public void deliverEvent(Event e)
933: {
934: if (!handleEvent (e))
935: {
936: synchronized (getTreeLock ())
937: {
938: Component parent = getParent ();
939:
940: if (parent != null)
941: parent.deliverEvent (e);
942: }
943: }
944: }
945:
946:
960: public Component getComponentAt(int x, int y)
961: {
962: return locate (x, y);
963: }
964:
965:
981: public Component locate(int x, int y)
982: {
983: synchronized (getTreeLock ())
984: {
985: if (!contains (x, y))
986: return null;
987: for (int i = 0; i < ncomponents; ++i)
988: {
989:
990: if (!component[i].isVisible ())
991: continue;
992:
993: int x2 = x - component[i].x;
994: int y2 = y - component[i].y;
995: if (component[i].contains (x2, y2))
996: return component[i];
997: }
998: return this;
999: }
1000: }
1001:
1002:
1014: public Component getComponentAt(Point p)
1015: {
1016: return getComponentAt (p.x, p.y);
1017: }
1018:
1019: public Component findComponentAt(int x, int y)
1020: {
1021: synchronized (getTreeLock ())
1022: {
1023: if (! contains(x, y))
1024: return null;
1025:
1026: for (int i = 0; i < ncomponents; ++i)
1027: {
1028:
1029: if (!component[i].isVisible())
1030: continue;
1031:
1032: int x2 = x - component[i].x;
1033: int y2 = y - component[i].y;
1034:
1035:
1036: if (component[i] instanceof Container)
1037: {
1038: Container k = (Container) component[i];
1039: Component r = k.findComponentAt(x2, y2);
1040: if (r != null)
1041: return r;
1042: }
1043: else if (component[i].contains(x2, y2))
1044: return component[i];
1045: }
1046:
1047: return this;
1048: }
1049: }
1050:
1051: public Component findComponentAt(Point p)
1052: {
1053: return findComponentAt(p.x, p.y);
1054: }
1055:
1056:
1061: public void addNotify()
1062: {
1063: super.addNotify();
1064: addNotifyContainerChildren();
1065: }
1066:
1067:
1072: public void removeNotify()
1073: {
1074: synchronized (getTreeLock ())
1075: {
1076: for (int i = 0; i < ncomponents; ++i)
1077: component[i].removeNotify();
1078: super.removeNotify();
1079: }
1080: }
1081:
1082:
1091: public boolean isAncestorOf(Component comp)
1092: {
1093: synchronized (getTreeLock ())
1094: {
1095: while (true)
1096: {
1097: if (comp == null)
1098: return false;
1099: if (comp == this)
1100: return true;
1101: comp = comp.getParent();
1102: }
1103: }
1104: }
1105:
1106:
1112: protected String paramString()
1113: {
1114: if (layoutMgr == null)
1115: return super.paramString();
1116:
1117: StringBuffer sb = new StringBuffer();
1118: sb.append(super.paramString());
1119: sb.append(",layout=");
1120: sb.append(layoutMgr.getClass().getName());
1121: return sb.toString();
1122: }
1123:
1124:
1131: public void list(PrintStream out, int indent)
1132: {
1133: synchronized (getTreeLock ())
1134: {
1135: super.list(out, indent);
1136: for (int i = 0; i < ncomponents; ++i)
1137: component[i].list(out, indent + 2);
1138: }
1139: }
1140:
1141:
1148: public void list(PrintWriter out, int indent)
1149: {
1150: synchronized (getTreeLock ())
1151: {
1152: super.list(out, indent);
1153: for (int i = 0; i < ncomponents; ++i)
1154: component[i].list(out, indent + 2);
1155: }
1156: }
1157:
1158:
1174: public void setFocusTraversalKeys(int id, Set keystrokes)
1175: {
1176: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1177: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1178: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1179: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1180: throw new IllegalArgumentException ();
1181:
1182: if (keystrokes == null)
1183: {
1184: Container parent = getParent ();
1185:
1186: while (parent != null)
1187: {
1188: if (parent.areFocusTraversalKeysSet (id))
1189: {
1190: keystrokes = parent.getFocusTraversalKeys (id);
1191: break;
1192: }
1193: parent = parent.getParent ();
1194: }
1195:
1196: if (keystrokes == null)
1197: keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
1198: getDefaultFocusTraversalKeys (id);
1199: }
1200:
1201: Set sa;
1202: Set sb;
1203: Set sc;
1204: String name;
1205: switch (id)
1206: {
1207: case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
1208: sa = getFocusTraversalKeys
1209: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1210: sb = getFocusTraversalKeys
1211: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1212: sc = getFocusTraversalKeys
1213: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1214: name = "forwardFocusTraversalKeys";
1215: break;
1216: case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
1217: sa = getFocusTraversalKeys
1218: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1219: sb = getFocusTraversalKeys
1220: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1221: sc = getFocusTraversalKeys
1222: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1223: name = "backwardFocusTraversalKeys";
1224: break;
1225: case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
1226: sa = getFocusTraversalKeys
1227: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1228: sb = getFocusTraversalKeys
1229: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1230: sc = getFocusTraversalKeys
1231: (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1232: name = "upCycleFocusTraversalKeys";
1233: break;
1234: case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
1235: sa = getFocusTraversalKeys
1236: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
1237: sb = getFocusTraversalKeys
1238: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
1239: sc = getFocusTraversalKeys
1240: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
1241: name = "downCycleFocusTraversalKeys";
1242: break;
1243: default:
1244: throw new IllegalArgumentException ();
1245: }
1246:
1247: int i = keystrokes.size ();
1248: Iterator iter = keystrokes.iterator ();
1249:
1250: while (--i >= 0)
1251: {
1252: Object o = iter.next ();
1253: if (!(o instanceof AWTKeyStroke)
1254: || sa.contains (o) || sb.contains (o) || sc.contains (o)
1255: || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
1256: throw new IllegalArgumentException ();
1257: }
1258:
1259: if (focusTraversalKeys == null)
1260: focusTraversalKeys = new Set[4];
1261:
1262: keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
1263: firePropertyChange (name, focusTraversalKeys[id], keystrokes);
1264:
1265: focusTraversalKeys[id] = keystrokes;
1266: }
1267:
1268:
1280: public Set getFocusTraversalKeys (int id)
1281: {
1282: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1283: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1284: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1285: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1286: throw new IllegalArgumentException ();
1287:
1288: Set s = null;
1289:
1290: if (focusTraversalKeys != null)
1291: s = focusTraversalKeys[id];
1292:
1293: if (s == null && parent != null)
1294: s = parent.getFocusTraversalKeys (id);
1295:
1296: return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
1297: .getDefaultFocusTraversalKeys(id)) : s;
1298: }
1299:
1300:
1314: public boolean areFocusTraversalKeysSet (int id)
1315: {
1316: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
1317: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
1318: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
1319: id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
1320: throw new IllegalArgumentException ();
1321:
1322: return focusTraversalKeys != null && focusTraversalKeys[id] != null;
1323: }
1324:
1325:
1340: public boolean isFocusCycleRoot (Container c)
1341: {
1342: if (this == c
1343: && isFocusCycleRoot ())
1344: return true;
1345:
1346: Container ancestor = getFocusCycleRootAncestor ();
1347:
1348: if (c == ancestor)
1349: return true;
1350:
1351: return false;
1352: }
1353:
1354:
1366: public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
1367: {
1368: focusTraversalPolicy = policy;
1369: }
1370:
1371:
1382: public FocusTraversalPolicy getFocusTraversalPolicy ()
1383: {
1384: if (!isFocusCycleRoot ())
1385: return null;
1386:
1387: if (focusTraversalPolicy == null)
1388: {
1389: Container ancestor = getFocusCycleRootAncestor ();
1390:
1391: if (ancestor != this)
1392: return ancestor.getFocusTraversalPolicy ();
1393: else
1394: {
1395: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1396:
1397: return manager.getDefaultFocusTraversalPolicy ();
1398: }
1399: }
1400: else
1401: return focusTraversalPolicy;
1402: }
1403:
1404:
1412: public boolean isFocusTraversalPolicySet ()
1413: {
1414: return focusTraversalPolicy == null;
1415: }
1416:
1417:
1433: public void setFocusCycleRoot (boolean focusCycleRoot)
1434: {
1435: this.focusCycleRoot = focusCycleRoot;
1436: }
1437:
1438:
1445: public boolean isFocusCycleRoot ()
1446: {
1447: return focusCycleRoot;
1448: }
1449:
1450:
1459: public void transferFocusDownCycle ()
1460: {
1461: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
1462:
1463: manager.downFocusCycle (this);
1464: }
1465:
1466:
1474: public void applyComponentOrientation (ComponentOrientation orientation)
1475: {
1476: if (orientation == null)
1477: throw new NullPointerException ();
1478: }
1479:
1480: public void addPropertyChangeListener (PropertyChangeListener listener)
1481: {
1482: if (listener == null)
1483: return;
1484:
1485: if (changeSupport == null)
1486: changeSupport = new PropertyChangeSupport (this);
1487:
1488: changeSupport.addPropertyChangeListener (listener);
1489: }
1490:
1491: public void addPropertyChangeListener (String name,
1492: PropertyChangeListener listener)
1493: {
1494: if (listener == null)
1495: return;
1496:
1497: if (changeSupport == null)
1498: changeSupport = new PropertyChangeSupport (this);
1499:
1500: changeSupport.addPropertyChangeListener (name, listener);
1501: }
1502:
1503:
1504:
1505:
1519: private void visitChildren(Graphics gfx, GfxVisitor visitor,
1520: boolean lightweightOnly)
1521: {
1522: synchronized (getTreeLock ())
1523: {
1524: for (int i = ncomponents - 1; i >= 0; --i)
1525: {
1526: Component comp = component[i];
1527: boolean applicable = comp.isVisible()
1528: && (comp.isLightweight() || !lightweightOnly);
1529:
1530: if (applicable)
1531: visitChild(gfx, visitor, comp);
1532: }
1533: }
1534: }
1535:
1536:
1549: private void visitChild(Graphics gfx, GfxVisitor visitor,
1550: Component comp)
1551: {
1552: Rectangle bounds = comp.getBounds();
1553: Rectangle oldClip = gfx.getClipBounds();
1554: if (oldClip == null)
1555: oldClip = bounds;
1556:
1557: Rectangle clip = oldClip.intersection(bounds);
1558:
1559: if (clip.isEmpty()) return;
1560:
1561: boolean clipped = false;
1562: boolean translated = false;
1563: try
1564: {
1565: gfx.setClip(clip.x, clip.y, clip.width, clip.height);
1566: clipped = true;
1567: gfx.translate(bounds.x, bounds.y);
1568: translated = true;
1569: visitor.visit(comp, gfx);
1570: }
1571: finally
1572: {
1573: if (translated)
1574: gfx.translate (-bounds.x, -bounds.y);
1575: if (clipped)
1576: gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
1577: }
1578: }
1579:
1580: void dispatchEventImpl(AWTEvent e)
1581: {
1582:
1583: if (dispatcher != null && dispatcher.handleEvent (e))
1584: return;
1585:
1586: if ((e.id <= ContainerEvent.CONTAINER_LAST
1587: && e.id >= ContainerEvent.CONTAINER_FIRST)
1588: && (containerListener != null
1589: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
1590: processEvent(e);
1591: else
1592: super.dispatchEventImpl(e);
1593: }
1594:
1595:
1605: boolean eventTypeEnabled(int eventId)
1606: {
1607: if(eventId <= ContainerEvent.CONTAINER_LAST
1608: && eventId >= ContainerEvent.CONTAINER_FIRST)
1609: return containerListener != null
1610: || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0;
1611: else
1612: return super.eventTypeEnabled(eventId);
1613: }
1614:
1615:
1616: Component findNextFocusComponent(Component child)
1617: {
1618: synchronized (getTreeLock ())
1619: {
1620: int start, end;
1621: if (child != null)
1622: {
1623: for (start = 0; start < ncomponents; ++start)
1624: {
1625: if (component[start] == child)
1626: break;
1627: }
1628: end = start;
1629:
1630: if (end == 0)
1631: end = ncomponents;
1632: ++start;
1633: }
1634: else
1635: {
1636: start = 0;
1637: end = ncomponents;
1638: }
1639:
1640: for (int j = start; j != end; ++j)
1641: {
1642: if (j >= ncomponents)
1643: {
1644:
1645:
1646:
1647:
1648: if (parent != null)
1649: return parent.findNextFocusComponent(this);
1650: j -= ncomponents;
1651: }
1652: if (component[j] instanceof Container)
1653: {
1654: Component c = component[j];
1655: c = c.findNextFocusComponent(null);
1656: if (c != null)
1657: return c;
1658: }
1659: else if (component[j].isFocusTraversable())
1660: return component[j];
1661: }
1662:
1663: return null;
1664: }
1665: }
1666:
1667: private void addNotifyContainerChildren()
1668: {
1669: synchronized (getTreeLock ())
1670: {
1671: for (int i = ncomponents; --i >= 0; )
1672: {
1673: component[i].addNotify();
1674: if (component[i].isLightweight ())
1675: {
1676:
1677:
1678:
1679: if (!this.isLightweight() && dispatcher == null)
1680: dispatcher = new LightweightDispatcher (this);
1681:
1682: if (dispatcher != null)
1683: dispatcher.enableEvents(component[i].eventMask);
1684:
1685: enableEvents(component[i].eventMask);
1686: if (peer != null && !isLightweight ())
1687: enableEvents (AWTEvent.PAINT_EVENT_MASK);
1688: }
1689: }
1690: }
1691: }
1692:
1693:
1708: private void readObject (ObjectInputStream s)
1709: throws ClassNotFoundException, IOException
1710: {
1711: s.defaultReadObject ();
1712: String key = (String) s.readObject ();
1713: while (key != null)
1714: {
1715: Object object = s.readObject ();
1716: if ("containerL".equals (key))
1717: addContainerListener((ContainerListener) object);
1718:
1719: else if ("focusTraversalPolicy".equals (key))
1720: setFocusTraversalPolicy ((FocusTraversalPolicy) object);
1721:
1722: key = (String) s.readObject();
1723: }
1724: }
1725:
1726:
1738: private void writeObject (ObjectOutputStream s) throws IOException
1739: {
1740: s.defaultWriteObject ();
1741: AWTEventMulticaster.save (s, "containerL", containerListener);
1742: if (focusTraversalPolicy instanceof Serializable)
1743: s.writeObject (focusTraversalPolicy);
1744: else
1745: s.writeObject (null);
1746: }
1747:
1748:
1749:
1750:
1753:
1754: abstract static class GfxVisitor
1755: {
1756: public abstract void visit(Component c, Graphics gfx);
1757: }
1758:
1759: static class GfxPaintVisitor extends GfxVisitor
1760: {
1761: public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
1762:
1763: public void visit(Component c, Graphics gfx)
1764: {
1765: c.paint(gfx);
1766: }
1767: }
1768:
1769: static class GfxPrintVisitor extends GfxVisitor
1770: {
1771: public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
1772:
1773: public void visit(Component c, Graphics gfx)
1774: {
1775: c.print(gfx);
1776: }
1777: }
1778:
1779: static class GfxPaintAllVisitor extends GfxVisitor
1780: {
1781: public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
1782:
1783: public void visit(Component c, Graphics gfx)
1784: {
1785: c.paintAll(gfx);
1786: }
1787: }
1788:
1789: static class GfxPrintAllVisitor extends GfxVisitor
1790: {
1791: public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
1792:
1793: public void visit(Component c, Graphics gfx)
1794: {
1795: c.printAll(gfx);
1796: }
1797: }
1798:
1799:
1806: protected class AccessibleAWTContainer extends AccessibleAWTComponent
1807: {
1808:
1811: private static final long serialVersionUID = 5081320404842566097L;
1812:
1813:
1818: protected ContainerListener accessibleContainerHandler
1819: = new AccessibleContainerHandler();
1820:
1821:
1824: protected AccessibleAWTContainer()
1825: {
1826: Container.this.addContainerListener(accessibleContainerHandler);
1827: }
1828:
1829:
1835: public int getAccessibleChildrenCount()
1836: {
1837: synchronized (getTreeLock ())
1838: {
1839: int count = 0;
1840: int i = component == null ? 0 : component.length;
1841: while (--i >= 0)
1842: if (component[i] instanceof Accessible)
1843: count++;
1844: return count;
1845: }
1846: }
1847:
1848:
1854: public Accessible getAccessibleChild(int i)
1855: {
1856: synchronized (getTreeLock ())
1857: {
1858: if (component == null)
1859: return null;
1860: int index = -1;
1861: while (i >= 0 && ++index < component.length)
1862: if (component[index] instanceof Accessible)
1863: i--;
1864: if (i < 0)
1865: return (Accessible) component[index];
1866: return null;
1867: }
1868: }
1869:
1870:
1880: public Accessible getAccessibleAt(Point p)
1881: {
1882: Component c = getComponentAt(p.x, p.y);
1883: return c != Container.this && c instanceof Accessible ? (Accessible) c
1884: : null;
1885: }
1886:
1887:
1895: protected class AccessibleContainerHandler implements ContainerListener
1896: {
1897:
1900: protected AccessibleContainerHandler()
1901: {
1902: }
1903:
1904:
1910: public void componentAdded(ContainerEvent e)
1911: {
1912: AccessibleAWTContainer.this.firePropertyChange
1913: (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild());
1914: }
1915:
1916:
1922: public void componentRemoved(ContainerEvent e)
1923: {
1924: AccessibleAWTContainer.this.firePropertyChange
1925: (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
1926: }
1927: }
1928: }
1929: }
1930:
1931:
1937: class LightweightDispatcher implements Serializable
1938: {
1939: private static final long serialVersionUID = 5184291520170872969L;
1940: private Container nativeContainer;
1941: private Cursor nativeCursor;
1942: private long eventMask;
1943:
1944: private transient Component pressedComponent;
1945: private transient Component lastComponentEntered;
1946: private transient int pressCount;
1947:
1948: LightweightDispatcher(Container c)
1949: {
1950: nativeContainer = c;
1951: }
1952:
1953: void enableEvents(long l)
1954: {
1955: eventMask |= l;
1956: }
1957:
1958: Component acquireComponentForMouseEvent(MouseEvent me)
1959: {
1960: int x = me.getX ();
1961: int y = me.getY ();
1962:
1963: Component mouseEventTarget = null;
1964:
1965: Component parent = nativeContainer;
1966: Component candidate = null;
1967: Point p = me.getPoint();
1968: while (candidate == null && parent != null)
1969: {
1970: candidate =
1971: AWTUtilities.getDeepestComponentAt(parent, p.x, p.y);
1972: if (candidate == null || (candidate.eventMask & me.getID()) == 0)
1973: {
1974: candidate = null;
1975: p = AWTUtilities.convertPoint(parent, p.x, p.y, parent.parent);
1976: parent = parent.parent;
1977: }
1978: }
1979:
1980:
1981:
1982:
1983: if (candidate == nativeContainer)
1984: candidate = null;
1985:
1986:
1987: if (lastComponentEntered != null
1988: && lastComponentEntered.isShowing()
1989: && lastComponentEntered != candidate)
1990: {
1991:
1992:
1993: if (AWTUtilities.isDescendingFrom(lastComponentEntered,
1994: nativeContainer))
1995: {
1996: Point tp = AWTUtilities.convertPoint(nativeContainer,
1997: x, y, lastComponentEntered);
1998: MouseEvent exited = new MouseEvent (lastComponentEntered,
1999: MouseEvent.MOUSE_EXITED,
2000: me.getWhen (),
2001: me.getModifiersEx (),
2002: tp.x, tp.y,
2003: me.getClickCount (),
2004: me.isPopupTrigger (),
2005: me.getButton ());
2006: lastComponentEntered.dispatchEvent (exited);
2007: }
2008: lastComponentEntered = null;
2009: }
2010:
2011:
2012: if (candidate != null)
2013: {
2014: mouseEventTarget = candidate;
2015: if (candidate.isLightweight()
2016: && candidate.isShowing()
2017: && candidate != nativeContainer
2018: && candidate != lastComponentEntered)
2019: {
2020: lastComponentEntered = mouseEventTarget;
2021: Point cp = AWTUtilities.convertPoint(nativeContainer,
2022: x, y, lastComponentEntered);
2023: MouseEvent entered = new MouseEvent (lastComponentEntered,
2024: MouseEvent.MOUSE_ENTERED,
2025: me.getWhen (),
2026: me.getModifiersEx (),
2027: cp.x, cp.y,
2028: me.getClickCount (),
2029: me.isPopupTrigger (),
2030: me.getButton ());
2031: lastComponentEntered.dispatchEvent (entered);
2032: }
2033: }
2034:
2035:
2036:
2037: int modifiers = me.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK
2038: | MouseEvent.BUTTON2_DOWN_MASK
2039: | MouseEvent.BUTTON3_DOWN_MASK);
2040: switch(me.getButton())
2041: {
2042: case MouseEvent.BUTTON1:
2043: modifiers &= ~MouseEvent.BUTTON1_DOWN_MASK;
2044: break;
2045: case MouseEvent.BUTTON2:
2046: modifiers &= ~MouseEvent.BUTTON2_DOWN_MASK;
2047: break;
2048: case MouseEvent.BUTTON3:
2049: modifiers &= ~MouseEvent.BUTTON3_DOWN_MASK;
2050: break;
2051: }
2052:
2053: if (me.getID() == MouseEvent.MOUSE_RELEASED
2054: || me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
2055: || me.getID() == MouseEvent.MOUSE_DRAGGED)
2056: {
2057:
2058:
2059:
2060:
2061:
2062:
2063:
2064: if (AWTUtilities.isDescendingFrom(pressedComponent, nativeContainer))
2065: mouseEventTarget = pressedComponent;
2066: }
2067: else if (me.getID() == MouseEvent.MOUSE_CLICKED)
2068: {
2069:
2070:
2071: if (candidate != pressedComponent)
2072: mouseEventTarget = null;
2073: else if (pressCount == 0)
2074: pressedComponent = null;
2075: }
2076: return mouseEventTarget;
2077: }
2078:
2079: boolean handleEvent(AWTEvent e)
2080: {
2081: if (e instanceof MouseEvent)
2082: {
2083: MouseEvent me = (MouseEvent) e;
2084:
2085:
2086:
2087: Component mouseEventTarget = acquireComponentForMouseEvent(me);
2088:
2089:
2090: if (mouseEventTarget != null
2091: && mouseEventTarget.isShowing()
2092: && e.getID() != MouseEvent.MOUSE_ENTERED
2093: && e.getID() != MouseEvent.MOUSE_EXITED)
2094: {
2095: switch (e.getID())
2096: {
2097: case MouseEvent.MOUSE_PRESSED:
2098: if (pressCount++ == 0)
2099: pressedComponent = mouseEventTarget;
2100: break;
2101: case MouseEvent.MOUSE_RELEASED:
2102:
2103:
2104:
2105: if (--pressCount == 0
2106: && mouseEventTarget != pressedComponent)
2107: pressedComponent = null;
2108: break;
2109: }
2110:
2111: MouseEvent newEvt =
2112: AWTUtilities.convertMouseEvent(nativeContainer, me,
2113: mouseEventTarget);
2114: mouseEventTarget.dispatchEvent(newEvt);
2115:
2116: if (newEvt.isConsumed())
2117: e.consume();
2118: }
2119: }
2120:
2121: return e.isConsumed();
2122: }
2123: }