8539 } |
8533 } |
8540 return true; |
8534 return true; |
8541 } |
8535 } |
8542 |
8536 |
8543 /** |
8537 /** |
8544 * This odd class is to help out a native component that has been |
8538 * Fix the location of the HW component in a LW container hierarchy. |
8545 * embedded in a lightweight component. Moving lightweight |
8539 */ |
8546 * components around and changing their visibility is not seen |
8540 final void relocateComponent() { |
8547 * by the native window system. This is a feature for lightweights, |
8541 synchronized (getTreeLock()) { |
8548 * but a problem for native components that depend upon the |
8542 if (peer == null) { |
8549 * lightweights. An instance of this class listens to the lightweight |
8543 return; |
8550 * parents of an associated native component (the outer class). |
8544 } |
8551 * |
8545 int nativeX = x; |
8552 * @author Timothy Prinzing |
8546 int nativeY = y; |
8553 */ |
8547 for (Component cont = getContainer(); |
8554 final class NativeInLightFixer implements ComponentListener, ContainerListener { |
8548 cont != null && cont.isLightweight(); |
8555 |
8549 cont = cont.getContainer()) |
8556 NativeInLightFixer() { |
|
8557 lightParents = new Vector(); |
|
8558 install(parent); |
|
8559 } |
|
8560 |
|
8561 void install(Container parent) { |
|
8562 lightParents.clear(); |
|
8563 Container p = parent; |
|
8564 boolean isLwParentsVisible = true; |
|
8565 // stash a reference to the components that are being observed so that |
|
8566 // we can reliably remove ourself as a listener later. |
|
8567 for (; p.peer instanceof LightweightPeer; p = p.parent) { |
|
8568 |
|
8569 // register listeners and stash a reference |
|
8570 p.addComponentListener(this); |
|
8571 p.addContainerListener(this); |
|
8572 lightParents.addElement(p); |
|
8573 isLwParentsVisible &= p.isVisible(); |
|
8574 } |
|
8575 // register with the native host (native parent of associated native) |
|
8576 // to get notified if the top-level lightweight is removed. |
|
8577 nativeHost = p; |
|
8578 p.addContainerListener(this); |
|
8579 |
|
8580 // kick start the fixup. Since the event isn't looked at |
|
8581 // we can simulate movement notification. |
|
8582 componentMoved(null); |
|
8583 if (!isLwParentsVisible) { |
|
8584 synchronized (getTreeLock()) { |
|
8585 if (peer != null) { |
|
8586 peer.hide(); |
|
8587 } |
|
8588 } |
|
8589 } |
|
8590 } |
|
8591 |
|
8592 void uninstall() { |
|
8593 if (nativeHost != null) { |
|
8594 removeReferences(); |
|
8595 } |
|
8596 } |
|
8597 |
|
8598 // --- ComponentListener ------------------------------------------- |
|
8599 |
|
8600 /** |
|
8601 * Invoked when one of the lightweight parents has been resized. |
|
8602 * This doesn't change the position of the native child so it |
|
8603 * is ignored. |
|
8604 */ |
|
8605 public void componentResized(ComponentEvent e) { |
|
8606 } |
|
8607 |
|
8608 /** |
|
8609 * Invoked when one of the lightweight parents has been moved. |
|
8610 * The native peer must be told of the new position which is |
|
8611 * relative to the native container that is hosting the |
|
8612 * lightweight components. |
|
8613 */ |
|
8614 public void componentMoved(ComponentEvent e) { |
|
8615 synchronized (getTreeLock()) { |
|
8616 int nativeX = x; |
|
8617 int nativeY = y; |
|
8618 for(Component c = parent; (c != null) && |
|
8619 (c.peer instanceof LightweightPeer); |
|
8620 c = c.parent) { |
|
8621 |
|
8622 nativeX += c.x; |
|
8623 nativeY += c.y; |
|
8624 } |
|
8625 if (peer != null) { |
|
8626 peer.setBounds(nativeX, nativeY, width, height, |
|
8627 ComponentPeer.SET_LOCATION); |
|
8628 } |
|
8629 } |
|
8630 } |
|
8631 |
|
8632 /** |
|
8633 * Invoked when a lightweight parent component has been |
|
8634 * shown. The associated native component must also be |
|
8635 * shown if it hasn't had an overriding hide done on it. |
|
8636 */ |
|
8637 public void componentShown(ComponentEvent e) { |
|
8638 if (shouldShow()) { |
|
8639 synchronized (getTreeLock()) { |
|
8640 if (peer != null) { |
|
8641 peer.show(); |
|
8642 } |
|
8643 } |
|
8644 } |
|
8645 } |
|
8646 |
|
8647 /** |
|
8648 * Invoked when one of the lightweight parents become visible. |
|
8649 * Returns true if component and all its lightweight |
|
8650 * parents are visible. |
|
8651 */ |
|
8652 private boolean shouldShow() { |
|
8653 boolean isLwParentsVisible = visible; |
|
8654 for (int i = lightParents.size() - 1; |
|
8655 i >= 0 && isLwParentsVisible; |
|
8656 i--) |
|
8657 { |
8550 { |
8658 isLwParentsVisible &= |
8551 nativeX += cont.x; |
8659 ((Container) lightParents.elementAt(i)).isVisible(); |
8552 nativeY += cont.y; |
8660 } |
8553 } |
8661 return isLwParentsVisible; |
8554 peer.setBounds(nativeX, nativeY, width, height, |
8662 } |
8555 ComponentPeer.SET_LOCATION); |
8663 |
8556 } |
8664 /** |
|
8665 * Invoked when component has been hidden. |
|
8666 */ |
|
8667 public void componentHidden(ComponentEvent e) { |
|
8668 if (visible) { |
|
8669 synchronized (getTreeLock()) { |
|
8670 if (peer != null) { |
|
8671 peer.hide(); |
|
8672 } |
|
8673 } |
|
8674 } |
|
8675 } |
|
8676 |
|
8677 // --- ContainerListener ------------------------------------ |
|
8678 |
|
8679 /** |
|
8680 * Invoked when a component has been added to a lightweight |
|
8681 * parent. This doesn't effect the native component. |
|
8682 */ |
|
8683 public void componentAdded(ContainerEvent e) { |
|
8684 } |
|
8685 |
|
8686 /** |
|
8687 * Invoked when a lightweight parent has been removed. |
|
8688 * This means the services of this listener are no longer |
|
8689 * required and it should remove all references (ie |
|
8690 * registered listeners). |
|
8691 */ |
|
8692 public void componentRemoved(ContainerEvent e) { |
|
8693 Component c = e.getChild(); |
|
8694 if (c == Component.this) { |
|
8695 removeReferences(); |
|
8696 } else { |
|
8697 int n = lightParents.size(); |
|
8698 for (int i = 0; i < n; i++) { |
|
8699 Container p = (Container) lightParents.elementAt(i); |
|
8700 if (p == c) { |
|
8701 removeReferences(); |
|
8702 break; |
|
8703 } |
|
8704 } |
|
8705 } |
|
8706 } |
|
8707 |
|
8708 /** |
|
8709 * Removes references to this object so it can be |
|
8710 * garbage collected. |
|
8711 */ |
|
8712 void removeReferences() { |
|
8713 int n = lightParents.size(); |
|
8714 for (int i = 0; i < n; i++) { |
|
8715 Container c = (Container) lightParents.elementAt(i); |
|
8716 c.removeComponentListener(this); |
|
8717 c.removeContainerListener(this); |
|
8718 } |
|
8719 nativeHost.removeContainerListener(this); |
|
8720 lightParents.clear(); |
|
8721 nativeHost = null; |
|
8722 } |
|
8723 |
|
8724 Vector lightParents; |
|
8725 Container nativeHost; |
|
8726 } |
8557 } |
8727 |
8558 |
8728 /** |
8559 /** |
8729 * Returns the <code>Window</code> ancestor of the component. |
8560 * Returns the <code>Window</code> ancestor of the component. |
8730 * @return Window ancestor of the component or component by itself if it is Window; |
8561 * @return Window ancestor of the component or component by itself if it is Window; |