| 1 7 package java.awt; 8 9 import java.io.PrintStream ; 10 import java.io.PrintWriter ; 11 import java.awt.peer.ContainerPeer; 12 import java.awt.peer.ComponentPeer; 13 import java.awt.peer.LightweightPeer; 14 import sun.awt.PeerEvent; 15 import java.awt.event.ComponentEvent ; 16 import java.awt.event.ContainerEvent ; 17 import java.awt.event.FocusEvent ; 18 import java.awt.event.HierarchyEvent ; 19 import java.awt.event.InputEvent ; 20 import java.awt.event.KeyEvent ; 21 import java.awt.event.MouseEvent ; 22 import java.awt.event.MouseWheelEvent ; 23 import java.awt.event.ContainerListener ; 24 import java.util.EventListener ; 25 import java.io.ObjectStreamField ; 26 import java.io.ObjectOutputStream ; 27 import java.io.ObjectInputStream ; 28 import java.io.IOException ; 29 import java.awt.event.AWTEventListener ; 30 import java.awt.event.WindowAdapter ; 31 import java.awt.event.WindowListener ; 32 import java.awt.event.WindowEvent ; 33 import java.awt.dnd.DropTarget ; 34 import java.util.HashSet ; 35 import java.util.LinkedList ; 36 import java.util.Set ; 37 import java.util.Iterator ; 38 import javax.accessibility.*; 39 import java.beans.PropertyChangeListener ; 40 import javax.swing.JRootPane ; 41 42 import sun.awt.AppContext; 43 import sun.awt.DebugHelper; 44 import sun.awt.SunToolkit; 45 import sun.awt.dnd.SunDropTargetEvent; 46 47 72 public class Container extends Component { 73 74 81 int ncomponents; 82 83 88 Component component[] = new Component [0]; 89 90 96 LayoutManager layoutMgr; 97 98 104 private LightweightDispatcher dispatcher; 105 106 124 private transient FocusTraversalPolicy focusTraversalPolicy; 125 126 138 private boolean focusCycleRoot = false; 139 140 141 146 private boolean focusTraversalPolicyProvider; 147 148 private transient Set printingThreads; 150 private transient boolean printing = false; 152 153 transient ContainerListener containerListener; 154 155 156 transient int listeningChildren; 157 transient int listeningBoundsChildren; 158 transient int descendantsCount; 159 160 163 private static final long serialVersionUID = 4613797578919906343L; 164 165 private static final DebugHelper dbg = DebugHelper.create(Container .class); 166 167 175 static final boolean INCLUDE_SELF = true; 176 177 184 static final boolean SEARCH_HEAVYWEIGHTS = true; 185 186 213 private static final ObjectStreamField [] serialPersistentFields = { 214 new ObjectStreamField ("ncomponents", Integer.TYPE), 215 new ObjectStreamField ("component", Component [].class), 216 new ObjectStreamField ("layoutMgr", LayoutManager .class), 217 new ObjectStreamField ("dispatcher", LightweightDispatcher.class), 218 new ObjectStreamField ("maxSize", Dimension .class), 219 new ObjectStreamField ("focusCycleRoot", Boolean.TYPE), 220 new ObjectStreamField ("containerSerializedDataVersion", Integer.TYPE), 221 new ObjectStreamField ("focusTraversalPolicyProvider", Boolean.TYPE), 222 }; 223 224 static { 225 226 Toolkit.loadLibraries(); 227 if (!GraphicsEnvironment.isHeadless()) { 228 initIDs(); 229 } 230 } 231 232 236 private static native void initIDs(); 237 238 244 public Container() { 245 } 246 247 void initializeFocusTraversalKeys() { 248 focusTraversalKeys = new Set [4]; 249 } 250 251 257 public int getComponentCount() { 258 return countComponents(); 259 } 260 261 265 @Deprecated  266 public int countComponents() { 267 return ncomponents; 268 } 269 270 277 public Component getComponent(int n) { 278 synchronized (getTreeLock()) { 279 if ((n < 0) || (n >= ncomponents)) { 280 throw new ArrayIndexOutOfBoundsException ("No such child: " + n); 281 } 282 return component[n]; 283 } 284 } 285 286 290 public Component [] getComponents() { 291 return getComponents_NoClientCode(); 292 } 293 final Component [] getComponents_NoClientCode() { 298 synchronized (getTreeLock()) { 299 Component list[] = new Component [ncomponents]; 300 System.arraycopy(component, 0, list, 0, ncomponents); 301 return list; 302 } 303 } 305 316 public Insets getInsets() { 317 return insets(); 318 } 319 320 324 @Deprecated  325 public Insets insets() { 326 if (this.peer != null && this.peer instanceof ContainerPeer) { 327 ContainerPeer peer = (ContainerPeer)this.peer; 328 return (Insets )peer.insets().clone(); 329 } 330 return new Insets (0, 0, 0, 0); 331 } 332 333 350 public Component add(Component comp) { 351 addImpl(comp, null, -1); 352 return comp; 353 } 354 355 363 public Component add(String name, Component comp) { 364 addImpl(comp, name, -1); 365 return comp; 366 } 367 368 389 public Component add(Component comp, int index) { 390 addImpl(comp, null, index); 391 return comp; 392 } 393 394 void checkTreeLock() { 395 if (!Thread.holdsLock(getTreeLock())) { 396 throw new IllegalStateException ("This function should be called while holding treeLock"); 397 } 398 } 399 410 private void checkAdding(Component comp, int index) { 411 checkTreeLock(); 412 413 GraphicsConfiguration thisGC = getGraphicsConfiguration(); 414 415 if (index > ncomponents || index < 0) { 416 throw new IllegalArgumentException ("illegal component position"); 417 } 418 if (comp.parent == this) { 419 if (index == ncomponents) { 420 throw new IllegalArgumentException ("illegal component position " + 421 index + " should be less then " + ncomponents); 422 } 423 } 424 if (comp instanceof Container ) { 425 for (Container cn = this; cn != null; cn=cn.parent) { 426 if (cn == comp) { 427 throw new IllegalArgumentException ("adding container's parent to itself"); 428 } 429 } 430 431 if (comp instanceof Window ) { 432 throw new IllegalArgumentException ("adding a window to a container"); 433 } 434 } 435 Window thisTopLevel = getContainingWindow(); 436 Window compTopLevel = comp.getContainingWindow(); 437 if (thisTopLevel != compTopLevel) { 438 throw new IllegalArgumentException ("component and container should be in the same top-level window"); 439 } 440 if (thisGC != null) { 441 comp.checkGD(thisGC.getDevice().getIDstring()); 442 } 443 } 444 445 453 private void removeDelicately(Component comp, Container newParent, int newIndex) { 454 checkTreeLock(); 455 456 int index = getComponentZOrder(comp); 457 if (isRemoveNotifyNeeded(comp, this, newParent)) { 458 comp.removeNotify(); 459 } 460 if (newParent != this) { 461 if (layoutMgr != null) { 462 layoutMgr.removeLayoutComponent(comp); 463 } 464 adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, 465 -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK)); 466 adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 467 -comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)); 468 adjustDescendants(-(comp.countHierarchyMembers())); 469 470 comp.parent = null; 471 System.arraycopy(component, index + 1, 472 component, index, 473 ncomponents - index - 1); 474 component[--ncomponents] = null; 475 476 if (valid) { 477 invalidate(); 478 } 479 } else { 480 if (newIndex > index) { if (newIndex-index > 0) { 482 System.arraycopy(component, index+1, component, index, newIndex-index); 483 } 484 } else { if (index-newIndex > 0) { 486 System.arraycopy(component, newIndex, component, newIndex+1, index-newIndex); 487 } 488 } 489 component[newIndex] = comp; 490 } 491 if (comp.parent == null) { if (containerListener != null || 493 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 || 494 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) { 495 ContainerEvent e = new ContainerEvent (this, 496 ContainerEvent.COMPONENT_REMOVED, 497 comp); 498 dispatchEvent(e); 499 500 } 501 comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp, 502 this, HierarchyEvent.PARENT_CHANGED, 503 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)); 504 if (peer != null && layoutMgr == null && isVisible()) { 505 updateCursorImmediately(); 506 } 507 } 508 } 509 510 516 boolean canContainFocusOwner(Component focusOwnerCandidate) { 517 if (!(isEnabled() && isDisplayable() 518 && isVisible() && isFocusable())) 519 { 520 return false; 521 } 522 if (isFocusCycleRoot()) { 523 FocusTraversalPolicy policy = getFocusTraversalPolicy(); 524 if (policy instanceof DefaultFocusTraversalPolicy ) { 525 if (!((DefaultFocusTraversalPolicy )policy).accept(focusOwnerCandidate)) { 526 return false; 527 } 528 } 529 } 530 synchronized(getTreeLock()) { 531 if (parent != null) { 532 return parent.canContainFocusOwner(focusOwnerCandidate); 533 } 534 } 535 return true; 536 } 537 538 544 private boolean hasHeavyweightChildren() { 545 checkTreeLock(); 546 boolean res = true; for (int i = 0; i < getComponentCount() && res; i++) { 548 Component child = getComponent(i); 549 res &= child.isLightweight(); 550 if (res && child instanceof Container ) { 551 res &= !((Container )child).hasHeavyweightChildren(); 552 } 553 } 554 return !res; 555 } 556 557 562 Container getHeavyweightContainer() { 563 checkTreeLock(); 564 if (peer != null && !(peer instanceof LightweightPeer)) { 565 return this; 566 } else { 567 return getNativeContainer(); 568 } 569 } 570 571 578 private static boolean isRemoveNotifyNeeded(Component comp, Container oldContainer, Container newContainer) { 579 if (oldContainer == null) { return false; 581 } 582 if (comp.peer == null) { return false; 584 } 585 if (newContainer.peer == null) { 586 return true; 588 } 589 590 if (comp.isLightweight()) { 593 if (comp instanceof Container ) { 594 return ((Container )comp).hasHeavyweightChildren(); 596 } else { 597 return false; 599 } 600 } 601 602 Container newNativeContainer = oldContainer.getHeavyweightContainer(); 604 Container oldNativeContainer = newContainer.getHeavyweightContainer(); 605 if (newNativeContainer != oldNativeContainer) { 606 return !comp.peer.isReparentSupported(); 609 } else { 610 return !comp.isLightweight() && 614 !((ContainerPeer)(newNativeContainer.peer)).isRestackSupported(); 615 } 616 } 617 618 664 public final void setComponentZOrder(Component comp, int index) { 665 synchronized (getTreeLock()) { 666 Container curParent = comp.parent; 668 if (curParent == this && index == getComponentZOrder(comp)) { 669 return; 670 } 671 checkAdding(comp, index); 672 if (curParent != null) { 673 curParent.removeDelicately(comp, this, index); 674 } 675 676 addDelicately(comp, curParent, index); 677 } 678 } 679 680 685 private void reparentTraverse(ContainerPeer parentPeer, Container child) { 686 checkTreeLock(); 687 688 for (int i = 0; i < child.getComponentCount(); i++) { 689 Component comp = child.getComponent(i); 690 if (comp.isLightweight()) { 691 if (comp instanceof Container ) { 694 reparentTraverse(parentPeer, (Container )comp); 695 } 696 } else { 697 comp.getPeer().reparent(parentPeer); 699 } 700 } 701 } 702 703 708 private void reparentChild(Component comp) { 709 checkTreeLock(); 710 if (comp == null) { 711 return; 712 } 713 if (comp.isLightweight()) { 714 if (comp instanceof Container ) { 716 reparentTraverse((ContainerPeer)getPeer(), (Container )comp); 718 } 719 } else { 720 comp.getPeer().reparent((ContainerPeer)getPeer()); 721 } 722 } 723 724 729 private void addDelicately(Component comp, Container curParent, int index) { 730 checkTreeLock(); 731 732 if (curParent != this) { 734 735 if (ncomponents == component.length) { 736 Component newcomponents[] = new Component [ncomponents * 2 + 1]; 737 System.arraycopy(component, 0, newcomponents, 0, ncomponents); 738 component = newcomponents; 739 } 740 if (index == -1 || index == ncomponents) { 741 component[ncomponents++] = comp; 742 } else { 743 System.arraycopy(component, index, component, 744 index + 1, ncomponents - index); 745 component[index] = comp; 746 ncomponents++; 747 } 748 comp.parent = this; 749 750 adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, 751 comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK)); 752 adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 753 comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)); 754 adjustDescendants(comp.countHierarchyMembers()); 755 } else { 756 if (index < ncomponents) { 757 component[index] = comp; 758 } 759 } 760 761 if (valid) { 762 invalidate(); 763 } 764 if (peer != null) { 765 if (comp.peer == null) { comp.addNotify(); 767 Container newNativeContainer = getHeavyweightContainer(); 769 if (((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported()) { 770 ((ContainerPeer)newNativeContainer.getPeer()).restack(); 771 } 772 } else { Container newNativeContainer = getHeavyweightContainer(); 775 Container oldNativeContainer = curParent.getHeavyweightContainer(); 776 if (oldNativeContainer != newNativeContainer) { 777 newNativeContainer.reparentChild(comp); 779 } 780 if ((!comp.isLightweight() || (comp instanceof Container )) 783 && ((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported()) 784 { 785 ((ContainerPeer)newNativeContainer.getPeer()).restack(); 786 } 787 if (!comp.isLightweight() && isLightweight()) { 788 if (!curParent.isLightweight()) { 791 comp.nativeInLightFixer = new NativeInLightFixer(); 794 } else { 795 comp.nativeInLightFixer.install(this); 798 } 799 } 800 } 801 } 802 if (curParent != this) { 803 804 if (layoutMgr != null) { 805 if (layoutMgr instanceof LayoutManager2 ) { 806 ((LayoutManager2 )layoutMgr).addLayoutComponent(comp, null); 807 } else { 808 layoutMgr.addLayoutComponent(null, comp); 809 } 810 } 811 if (containerListener != null || 812 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 || 813 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) { 814 ContainerEvent  |