jdk/src/share/classes/java/awt/Component.java
changeset 130 11eb29307cfb
parent 126 b37abdfa7875
child 432 ff3aa6ee3572
child 466 6acd5ec503a8
equal deleted inserted replaced
129:f995b9c9c5fa 130:11eb29307cfb
  6490             } else {
  6490             } else {
  6491                 // It's native.  If the parent is lightweight it
  6491                 // It's native.  If the parent is lightweight it
  6492                 // will need some help.
  6492                 // will need some help.
  6493                 Container parent = this.parent;
  6493                 Container parent = this.parent;
  6494                 if (parent != null && parent.peer instanceof LightweightPeer) {
  6494                 if (parent != null && parent.peer instanceof LightweightPeer) {
  6495                     nativeInLightFixer = new NativeInLightFixer();
  6495                     relocateComponent();
  6496                 }
  6496                 }
  6497             }
  6497             }
  6498             invalidate();
  6498             invalidate();
  6499 
  6499 
  6500             int npopups = (popups != null? popups.size() : 0);
  6500             int npopups = (popups != null? popups.size() : 0);
  6599             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
  6599             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
  6600                 InputContext inputContext = getInputContext();
  6600                 InputContext inputContext = getInputContext();
  6601                 if (inputContext != null) {
  6601                 if (inputContext != null) {
  6602                     inputContext.removeNotify(this);
  6602                     inputContext.removeNotify(this);
  6603                 }
  6603                 }
  6604             }
       
  6605 
       
  6606             if (nativeInLightFixer != null) {
       
  6607                 nativeInLightFixer.uninstall();
       
  6608             }
  6604             }
  6609 
  6605 
  6610             ComponentPeer p = peer;
  6606             ComponentPeer p = peer;
  6611             if (p != null) {
  6607             if (p != null) {
  6612                 boolean isLightweight = isLightweight();
  6608                 boolean isLightweight = isLightweight();
  8512             throw new NullPointerException();
  8508             throw new NullPointerException();
  8513         }
  8509         }
  8514         setComponentOrientation(orientation);
  8510         setComponentOrientation(orientation);
  8515     }
  8511     }
  8516 
  8512 
  8517     transient NativeInLightFixer nativeInLightFixer;
       
  8518 
       
  8519     /**
  8513     /**
  8520      * Checks that this component meets the prerequesites to be focus owner:
  8514      * Checks that this component meets the prerequesites to be focus owner:
  8521      * - it is enabled, visible, focusable
  8515      * - it is enabled, visible, focusable
  8522      * - it's parents are all enabled and showing
  8516      * - it's parents are all enabled and showing
  8523      * - top-level window is focusable
  8517      * - top-level window is focusable
  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;