144 * focus traversal unless one of the up- or down-cycle keys is pressed.
145 * Normal traversal is limited to this Container, and all of this
146 * Container's descendants that are not descendants of inferior focus cycle
147 * roots.
148 *
149 * @see #setFocusCycleRoot
150 * @see #isFocusCycleRoot
151 * @since 1.4
152 */
153 private boolean focusCycleRoot = false;
154
155
156 /**
157 * Stores the value of focusTraversalPolicyProvider property.
158 * @since 1.5
159 * @see #setFocusTraversalPolicyProvider
160 */
161 private boolean focusTraversalPolicyProvider;
162
163 // keeps track of the threads that are printing this component
164 private transient Set printingThreads;
165 // True if there is at least one thread that's printing this component
166 private transient boolean printing = false;
167
168 transient ContainerListener containerListener;
169
170 /* HierarchyListener and HierarchyBoundsListener support */
171 transient int listeningChildren;
172 transient int listeningBoundsChildren;
173 transient int descendantsCount;
174
175 /* Non-opaque window support -- see Window.setLayersOpaque */
176 transient Color preserveBackgroundColor = null;
177
178 /**
179 * JDK 1.1 serialVersionUID
180 */
181 private static final long serialVersionUID = 4613797578919906343L;
182
183 /**
184 * A constant which toggles one of the controllable behaviors
258 public void validateUnconditionally(Container cont) {
259 cont.validateUnconditionally();
260 }
261 });
262 }
263
264 /**
265 * Initialize JNI field and method IDs for fields that may be
266 called from C.
267 */
268 private static native void initIDs();
269
270 /**
271 * Constructs a new Container. Containers can be extended directly,
272 * but are lightweight in this case and must be contained by a parent
273 * somewhere higher up in the component tree that is native.
274 * (such as Frame for example).
275 */
276 public Container() {
277 }
278
279 void initializeFocusTraversalKeys() {
280 focusTraversalKeys = new Set[4];
281 }
282
283 /**
284 * Gets the number of components in this panel.
285 * <p>
286 * Note: This method should be called under AWT tree lock.
287 *
288 * @return the number of components in this panel.
289 * @see #getComponent
290 * @since JDK1.1
291 * @see Component#getTreeLock()
292 */
293 public int getComponentCount() {
294 return countComponents();
295 }
296
297 /**
298 * @deprecated As of JDK version 1.1,
777 }
778
779 /**
780 * Traverses the tree of components and reparents children heavyweight component
781 * to new heavyweight parent.
782 * @since 1.5
783 */
784 private void reparentTraverse(ContainerPeer parentPeer, Container child) {
785 checkTreeLock();
786
787 for (int i = 0; i < child.getComponentCount(); i++) {
788 Component comp = child.getComponent(i);
789 if (comp.isLightweight()) {
790 // If components is lightweight check if it is container
791 // If it is container it might contain heavyweight children we need to reparent
792 if (comp instanceof Container) {
793 reparentTraverse(parentPeer, (Container)comp);
794 }
795 } else {
796 // Q: Need to update NativeInLightFixer?
797 comp.getPeer().reparent(parentPeer);
798 }
799 }
800 }
801
802 /**
803 * Reparents child component peer to this container peer.
804 * Container must be heavyweight.
805 * @since 1.5
806 */
807 private void reparentChild(Component comp) {
808 checkTreeLock();
809 if (comp == null) {
810 return;
811 }
812 if (comp.isLightweight()) {
813 // If component is lightweight container we need to reparent all its explicit heavyweight children
814 if (comp instanceof Container) {
815 // Traverse component's tree till depth-first until encountering heavyweight component
816 reparentTraverse((ContainerPeer)getPeer(), (Container)comp);
817 }
818 } else {
819 comp.getPeer().reparent((ContainerPeer)getPeer());
820 }
821 }
822
823 /**
824 * Adds component to this container. Tries to minimize side effects of this adding -
825 * doesn't call remove notify if it is not required.
826 * @since 1.5
827 */
828 private void addDelicately(Component comp, Container curParent, int index) {
829 checkTreeLock();
830
831 // Check if moving between containers
832 if (curParent != this) {
833 //index == -1 means add to the end.
834 if (index == -1) {
835 component.add(comp);
836 } else {
837 component.add(index, comp);
838 }
839 comp.parent = this;
1989 }
1990 }
1991
1992 /**
1993 * Prints the container. This forwards the print to any lightweight
1994 * components that are children of this container. If this method is
1995 * reimplemented, super.print(g) should be called so that lightweight
1996 * components are properly rendered. If a child component is entirely
1997 * clipped by the current clipping setting in g, print() will not be
1998 * forwarded to that child.
1999 *
2000 * @param g the specified Graphics window
2001 * @see Component#update(Graphics)
2002 */
2003 public void print(Graphics g) {
2004 if (isShowing()) {
2005 Thread t = Thread.currentThread();
2006 try {
2007 synchronized (getObjectLock()) {
2008 if (printingThreads == null) {
2009 printingThreads = new HashSet();
2010 }
2011 printingThreads.add(t);
2012 printing = true;
2013 }
2014 super.print(g); // By default, Component.print() calls paint()
2015 } finally {
2016 synchronized (getObjectLock()) {
2017 printingThreads.remove(t);
2018 printing = !printingThreads.isEmpty();
2019 }
2020 }
2021
2022 GraphicsCallback.PrintCallback.getInstance().
2023 runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
2024 }
2025 }
2026
2027 /**
2028 * Paints each of the components in this container.
2029 * @param g the graphics context.
2131 public synchronized void removeContainerListener(ContainerListener l) {
2132 if (l == null) {
2133 return;
2134 }
2135 containerListener = AWTEventMulticaster.remove(containerListener, l);
2136 }
2137
2138 /**
2139 * Returns an array of all the container listeners
2140 * registered on this container.
2141 *
2142 * @return all of this container's <code>ContainerListener</code>s
2143 * or an empty array if no container
2144 * listeners are currently registered
2145 *
2146 * @see #addContainerListener
2147 * @see #removeContainerListener
2148 * @since 1.4
2149 */
2150 public synchronized ContainerListener[] getContainerListeners() {
2151 return (ContainerListener[]) (getListeners(ContainerListener.class));
2152 }
2153
2154 /**
2155 * Returns an array of all the objects currently registered
2156 * as <code><em>Foo</em>Listener</code>s
2157 * upon this <code>Container</code>.
2158 * <code><em>Foo</em>Listener</code>s are registered using the
2159 * <code>add<em>Foo</em>Listener</code> method.
2160 *
2161 * <p>
2162 * You can specify the <code>listenerType</code> argument
2163 * with a class literal, such as
2164 * <code><em>Foo</em>Listener.class</code>.
2165 * For example, you can query a
2166 * <code>Container</code> <code>c</code>
2167 * for its container listeners with the following code:
2168 *
2169 * <pre>ContainerListener[] cls = (ContainerListener[])(c.getListeners(ContainerListener.class));</pre>
2170 *
2171 * If no such listeners exist, this method returns an empty array.
2582 * otherwise returns <code>null</code>.
2583 * This method is similar to {@link Component#getMousePosition()} with the exception
2584 * that it can take the <code>Container</code>'s children into account.
2585 * If <code>allowChildren</code> is <code>false</code>, this method will return
2586 * a non-null value only if the mouse pointer is above the <code>Container</code>
2587 * directly, not above the part obscured by children.
2588 * If <code>allowChildren</code> is <code>true</code>, this method returns
2589 * a non-null value if the mouse pointer is above <code>Container</code> or any
2590 * of its descendants.
2591 *
2592 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2593 * @param allowChildren true if children should be taken into account
2594 * @see Component#getMousePosition
2595 * @return mouse coordinates relative to this <code>Component</code>, or null
2596 * @since 1.5
2597 */
2598 public Point getMousePosition(boolean allowChildren) throws HeadlessException {
2599 if (GraphicsEnvironment.isHeadless()) {
2600 throw new HeadlessException();
2601 }
2602 PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged(
2603 new java.security.PrivilegedAction() {
2604 public Object run() {
2605 return MouseInfo.getPointerInfo();
2606 }
2607 }
2608 );
2609 synchronized (getTreeLock()) {
2610 Component inTheSameWindow = findUnderMouseInWindow(pi);
2611 if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) {
2612 return pointRelativeToComponent(pi.getLocation());
2613 }
2614 return null;
2615 }
2616 }
2617
2618 boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
2619 return this == comp || (allowChildren && isParentOf(comp));
2620 }
2621
2622 /**
2623 * Locates the visible child component that contains the specified
2624 * position. The top-most child component is returned in the case
2665 return null;
2666 }
2667
2668 final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
2669 checkTreeLock();
2670
2671 if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
2672 return null;
2673 }
2674
2675 // Two passes: see comment in sun.awt.SunGraphicsCallback
2676 for (int i = 0; i < component.size(); i++) {
2677 Component comp = component.get(i);
2678 if (comp != null &&
2679 !(comp.peer instanceof LightweightPeer)) {
2680 if (comp instanceof Container) {
2681 comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2682 y - comp.y,
2683 ignoreEnabled);
2684 } else {
2685 comp = comp.locate(x - comp.x, y - comp.y);
2686 }
2687 if (comp != null && comp.visible &&
2688 (ignoreEnabled || comp.enabled))
2689 {
2690 return comp;
2691 }
2692 }
2693 }
2694 for (int i = 0; i < component.size(); i++) {
2695 Component comp = component.get(i);
2696 if (comp != null &&
2697 comp.peer instanceof LightweightPeer) {
2698 if (comp instanceof Container) {
2699 comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2700 y - comp.y,
2701 ignoreEnabled);
2702 } else {
2703 comp = comp.locate(x - comp.x, y - comp.y);
2704 }
2705 if (comp != null && comp.visible &&
2706 (ignoreEnabled || comp.enabled))
2707 {
2708 return comp;
2709 }
2710 }
2711 }
2712
2713 return this;
2714 }
2715
2716 /**
2717 * Locates the visible child component that contains the specified
2718 * point. The top-most child component is returned in the case
2719 * where there is overlap in the components. If the containing child
2720 * component is a Container, this method will continue searching for
2721 * the deepest nested child component. Components which are not
2722 * visible are ignored during the search.<p>
2723 *
4135 }
4136 if (comp instanceof Container &&
4137 ((Container)comp).hasHeavyweightDescendants()) {
4138 ((Container)comp).recursiveApplyCurrentShape();
4139 }
4140 }
4141 }
4142
4143 private void recursiveShowHeavyweightChildren() {
4144 if (!hasHeavyweightDescendants() || !isVisible()) {
4145 return;
4146 }
4147 for (int index = 0; index < getComponentCount(); index++) {
4148 Component comp = getComponent(index);
4149 if (comp.isLightweight()) {
4150 if (comp instanceof Container) {
4151 ((Container)comp).recursiveShowHeavyweightChildren();
4152 }
4153 } else {
4154 if (comp.isVisible()) {
4155 ComponentPeer peer = comp.getPeer();
4156 if (peer != null) {
4157 peer.setVisible(true);
4158 }
4159 }
4160 }
4161 }
4162 }
4163
4164 private void recursiveHideHeavyweightChildren() {
4165 if (!hasHeavyweightDescendants()) {
4166 return;
4167 }
4168 for (int index = 0; index < getComponentCount(); index++) {
4169 Component comp = getComponent(index);
4170 if (comp.isLightweight()) {
4171 if (comp instanceof Container) {
4172 ((Container)comp).recursiveHideHeavyweightChildren();
4173 }
4174 } else {
4175 if (comp.isVisible()) {
4176 ComponentPeer peer = comp.getPeer();
4177 if (peer != null) {
4178 peer.setVisible(false);
4179 }
4180 }
4181 }
4182 }
4183 }
4184
4185 private void recursiveRelocateHeavyweightChildren(Point origin) {
4186 for (int index = 0; index < getComponentCount(); index++) {
4187 Component comp = getComponent(index);
4188 if (comp.isLightweight()) {
4189 if (comp instanceof Container &&
4190 ((Container)comp).hasHeavyweightDescendants())
4191 {
4192 final Point newOrigin = new Point(origin);
4193 newOrigin.translate(comp.getX(), comp.getY());
4194 ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
4195 }
4196 } else {
4197 ComponentPeer peer = comp.getPeer();
4198 if (peer != null) {
4199 peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
4200 comp.getWidth(), comp.getHeight(),
4201 ComponentPeer.SET_LOCATION);
4202 }
4203 }
4204 }
4205 }
4206
4207 /**
4208 * Checks if the container and its direct lightweight containers are
4209 * visible.
4210 *
4211 * Consider the heavyweight container hides or shows the HW descendants
4212 * automatically. Therefore we care of LW containers' visibility only.
4213 *
4214 * This method MUST be invoked under the TreeLock.
4215 */
4216 final boolean isRecursivelyVisibleUpToHeavyweightContainer() {
4217 if (!isLightweight()) {
4218 return true;
4219 }
4620
4621 if (targetEnter != null) {
4622 retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
4623 }
4624 if (id == MouseEvent.MOUSE_ENTERED) {
4625 // consume native enter event if we generate one
4626 e.consume();
4627 }
4628
4629 targetLastEntered = targetEnter;
4630 }
4631
4632 /*
4633 * Listens to global mouse drag events so even drags originating
4634 * from other heavyweight containers will generate enter/exit
4635 * events in this container
4636 */
4637 private void startListeningForOtherDrags() {
4638 //System.out.println("Adding AWTEventListener");
4639 java.security.AccessController.doPrivileged(
4640 new java.security.PrivilegedAction() {
4641 public Object run() {
4642 nativeContainer.getToolkit().addAWTEventListener(
4643 LightweightDispatcher.this,
4644 AWTEvent.MOUSE_EVENT_MASK |
4645 AWTEvent.MOUSE_MOTION_EVENT_MASK);
4646 return null;
4647 }
4648 }
4649 );
4650 }
4651
4652 private void stopListeningForOtherDrags() {
4653 //System.out.println("Removing AWTEventListener");
4654 java.security.AccessController.doPrivileged(
4655 new java.security.PrivilegedAction() {
4656 public Object run() {
4657 nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this);
4658 return null;
4659 }
4660 }
4661 );
4662 }
4663
4664 /*
4665 * (Implementation of AWTEventListener)
4666 * Listen for drag events posted in other hw components so we can
4667 * track enter/exit regardless of where a drag originated
4668 */
4669 public void eventDispatched(AWTEvent e) {
4670 boolean isForeignDrag = (e instanceof MouseEvent) &&
4671 !(e instanceof SunDropTargetEvent) &&
4672 (e.id == MouseEvent.MOUSE_DRAGGED) &&
4673 (e.getSource() != nativeContainer);
4674
4675 if (!isForeignDrag) {
|
144 * focus traversal unless one of the up- or down-cycle keys is pressed.
145 * Normal traversal is limited to this Container, and all of this
146 * Container's descendants that are not descendants of inferior focus cycle
147 * roots.
148 *
149 * @see #setFocusCycleRoot
150 * @see #isFocusCycleRoot
151 * @since 1.4
152 */
153 private boolean focusCycleRoot = false;
154
155
156 /**
157 * Stores the value of focusTraversalPolicyProvider property.
158 * @since 1.5
159 * @see #setFocusTraversalPolicyProvider
160 */
161 private boolean focusTraversalPolicyProvider;
162
163 // keeps track of the threads that are printing this component
164 private transient Set<Thread> printingThreads;
165 // True if there is at least one thread that's printing this component
166 private transient boolean printing = false;
167
168 transient ContainerListener containerListener;
169
170 /* HierarchyListener and HierarchyBoundsListener support */
171 transient int listeningChildren;
172 transient int listeningBoundsChildren;
173 transient int descendantsCount;
174
175 /* Non-opaque window support -- see Window.setLayersOpaque */
176 transient Color preserveBackgroundColor = null;
177
178 /**
179 * JDK 1.1 serialVersionUID
180 */
181 private static final long serialVersionUID = 4613797578919906343L;
182
183 /**
184 * A constant which toggles one of the controllable behaviors
258 public void validateUnconditionally(Container cont) {
259 cont.validateUnconditionally();
260 }
261 });
262 }
263
264 /**
265 * Initialize JNI field and method IDs for fields that may be
266 called from C.
267 */
268 private static native void initIDs();
269
270 /**
271 * Constructs a new Container. Containers can be extended directly,
272 * but are lightweight in this case and must be contained by a parent
273 * somewhere higher up in the component tree that is native.
274 * (such as Frame for example).
275 */
276 public Container() {
277 }
278 @SuppressWarnings({"unchecked","rawtypes"})
279 void initializeFocusTraversalKeys() {
280 focusTraversalKeys = new Set[4];
281 }
282
283 /**
284 * Gets the number of components in this panel.
285 * <p>
286 * Note: This method should be called under AWT tree lock.
287 *
288 * @return the number of components in this panel.
289 * @see #getComponent
290 * @since JDK1.1
291 * @see Component#getTreeLock()
292 */
293 public int getComponentCount() {
294 return countComponents();
295 }
296
297 /**
298 * @deprecated As of JDK version 1.1,
777 }
778
779 /**
780 * Traverses the tree of components and reparents children heavyweight component
781 * to new heavyweight parent.
782 * @since 1.5
783 */
784 private void reparentTraverse(ContainerPeer parentPeer, Container child) {
785 checkTreeLock();
786
787 for (int i = 0; i < child.getComponentCount(); i++) {
788 Component comp = child.getComponent(i);
789 if (comp.isLightweight()) {
790 // If components is lightweight check if it is container
791 // If it is container it might contain heavyweight children we need to reparent
792 if (comp instanceof Container) {
793 reparentTraverse(parentPeer, (Container)comp);
794 }
795 } else {
796 // Q: Need to update NativeInLightFixer?
797 comp.peer.reparent(parentPeer);
798 }
799 }
800 }
801
802 /**
803 * Reparents child component peer to this container peer.
804 * Container must be heavyweight.
805 * @since 1.5
806 */
807 private void reparentChild(Component comp) {
808 checkTreeLock();
809 if (comp == null) {
810 return;
811 }
812 if (comp.isLightweight()) {
813 // If component is lightweight container we need to reparent all its explicit heavyweight children
814 if (comp instanceof Container) {
815 // Traverse component's tree till depth-first until encountering heavyweight component
816 reparentTraverse((ContainerPeer)peer, (Container)comp);
817 }
818 } else {
819 comp.peer.reparent((ContainerPeer)peer);
820 }
821 }
822
823 /**
824 * Adds component to this container. Tries to minimize side effects of this adding -
825 * doesn't call remove notify if it is not required.
826 * @since 1.5
827 */
828 private void addDelicately(Component comp, Container curParent, int index) {
829 checkTreeLock();
830
831 // Check if moving between containers
832 if (curParent != this) {
833 //index == -1 means add to the end.
834 if (index == -1) {
835 component.add(comp);
836 } else {
837 component.add(index, comp);
838 }
839 comp.parent = this;
1989 }
1990 }
1991
1992 /**
1993 * Prints the container. This forwards the print to any lightweight
1994 * components that are children of this container. If this method is
1995 * reimplemented, super.print(g) should be called so that lightweight
1996 * components are properly rendered. If a child component is entirely
1997 * clipped by the current clipping setting in g, print() will not be
1998 * forwarded to that child.
1999 *
2000 * @param g the specified Graphics window
2001 * @see Component#update(Graphics)
2002 */
2003 public void print(Graphics g) {
2004 if (isShowing()) {
2005 Thread t = Thread.currentThread();
2006 try {
2007 synchronized (getObjectLock()) {
2008 if (printingThreads == null) {
2009 printingThreads = new HashSet<>();
2010 }
2011 printingThreads.add(t);
2012 printing = true;
2013 }
2014 super.print(g); // By default, Component.print() calls paint()
2015 } finally {
2016 synchronized (getObjectLock()) {
2017 printingThreads.remove(t);
2018 printing = !printingThreads.isEmpty();
2019 }
2020 }
2021
2022 GraphicsCallback.PrintCallback.getInstance().
2023 runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
2024 }
2025 }
2026
2027 /**
2028 * Paints each of the components in this container.
2029 * @param g the graphics context.
2131 public synchronized void removeContainerListener(ContainerListener l) {
2132 if (l == null) {
2133 return;
2134 }
2135 containerListener = AWTEventMulticaster.remove(containerListener, l);
2136 }
2137
2138 /**
2139 * Returns an array of all the container listeners
2140 * registered on this container.
2141 *
2142 * @return all of this container's <code>ContainerListener</code>s
2143 * or an empty array if no container
2144 * listeners are currently registered
2145 *
2146 * @see #addContainerListener
2147 * @see #removeContainerListener
2148 * @since 1.4
2149 */
2150 public synchronized ContainerListener[] getContainerListeners() {
2151 return getListeners(ContainerListener.class);
2152 }
2153
2154 /**
2155 * Returns an array of all the objects currently registered
2156 * as <code><em>Foo</em>Listener</code>s
2157 * upon this <code>Container</code>.
2158 * <code><em>Foo</em>Listener</code>s are registered using the
2159 * <code>add<em>Foo</em>Listener</code> method.
2160 *
2161 * <p>
2162 * You can specify the <code>listenerType</code> argument
2163 * with a class literal, such as
2164 * <code><em>Foo</em>Listener.class</code>.
2165 * For example, you can query a
2166 * <code>Container</code> <code>c</code>
2167 * for its container listeners with the following code:
2168 *
2169 * <pre>ContainerListener[] cls = (ContainerListener[])(c.getListeners(ContainerListener.class));</pre>
2170 *
2171 * If no such listeners exist, this method returns an empty array.
2582 * otherwise returns <code>null</code>.
2583 * This method is similar to {@link Component#getMousePosition()} with the exception
2584 * that it can take the <code>Container</code>'s children into account.
2585 * If <code>allowChildren</code> is <code>false</code>, this method will return
2586 * a non-null value only if the mouse pointer is above the <code>Container</code>
2587 * directly, not above the part obscured by children.
2588 * If <code>allowChildren</code> is <code>true</code>, this method returns
2589 * a non-null value if the mouse pointer is above <code>Container</code> or any
2590 * of its descendants.
2591 *
2592 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2593 * @param allowChildren true if children should be taken into account
2594 * @see Component#getMousePosition
2595 * @return mouse coordinates relative to this <code>Component</code>, or null
2596 * @since 1.5
2597 */
2598 public Point getMousePosition(boolean allowChildren) throws HeadlessException {
2599 if (GraphicsEnvironment.isHeadless()) {
2600 throw new HeadlessException();
2601 }
2602 PointerInfo pi = java.security.AccessController.doPrivileged(
2603 new java.security.PrivilegedAction<PointerInfo>() {
2604 public PointerInfo run() {
2605 return MouseInfo.getPointerInfo();
2606 }
2607 }
2608 );
2609 synchronized (getTreeLock()) {
2610 Component inTheSameWindow = findUnderMouseInWindow(pi);
2611 if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) {
2612 return pointRelativeToComponent(pi.getLocation());
2613 }
2614 return null;
2615 }
2616 }
2617
2618 boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
2619 return this == comp || (allowChildren && isParentOf(comp));
2620 }
2621
2622 /**
2623 * Locates the visible child component that contains the specified
2624 * position. The top-most child component is returned in the case
2665 return null;
2666 }
2667
2668 final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
2669 checkTreeLock();
2670
2671 if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
2672 return null;
2673 }
2674
2675 // Two passes: see comment in sun.awt.SunGraphicsCallback
2676 for (int i = 0; i < component.size(); i++) {
2677 Component comp = component.get(i);
2678 if (comp != null &&
2679 !(comp.peer instanceof LightweightPeer)) {
2680 if (comp instanceof Container) {
2681 comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2682 y - comp.y,
2683 ignoreEnabled);
2684 } else {
2685 comp = comp.getComponentAt(x - comp.x, y - comp.y);
2686 }
2687 if (comp != null && comp.visible &&
2688 (ignoreEnabled || comp.enabled))
2689 {
2690 return comp;
2691 }
2692 }
2693 }
2694 for (int i = 0; i < component.size(); i++) {
2695 Component comp = component.get(i);
2696 if (comp != null &&
2697 comp.peer instanceof LightweightPeer) {
2698 if (comp instanceof Container) {
2699 comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2700 y - comp.y,
2701 ignoreEnabled);
2702 } else {
2703 comp = comp.getComponentAt(x - comp.x, y - comp.y);
2704 }
2705 if (comp != null && comp.visible &&
2706 (ignoreEnabled || comp.enabled))
2707 {
2708 return comp;
2709 }
2710 }
2711 }
2712
2713 return this;
2714 }
2715
2716 /**
2717 * Locates the visible child component that contains the specified
2718 * point. The top-most child component is returned in the case
2719 * where there is overlap in the components. If the containing child
2720 * component is a Container, this method will continue searching for
2721 * the deepest nested child component. Components which are not
2722 * visible are ignored during the search.<p>
2723 *
4135 }
4136 if (comp instanceof Container &&
4137 ((Container)comp).hasHeavyweightDescendants()) {
4138 ((Container)comp).recursiveApplyCurrentShape();
4139 }
4140 }
4141 }
4142
4143 private void recursiveShowHeavyweightChildren() {
4144 if (!hasHeavyweightDescendants() || !isVisible()) {
4145 return;
4146 }
4147 for (int index = 0; index < getComponentCount(); index++) {
4148 Component comp = getComponent(index);
4149 if (comp.isLightweight()) {
4150 if (comp instanceof Container) {
4151 ((Container)comp).recursiveShowHeavyweightChildren();
4152 }
4153 } else {
4154 if (comp.isVisible()) {
4155 if (comp.peer != null) {
4156 comp.peer.setVisible(true);
4157 }
4158 }
4159 }
4160 }
4161 }
4162
4163 private void recursiveHideHeavyweightChildren() {
4164 if (!hasHeavyweightDescendants()) {
4165 return;
4166 }
4167 for (int index = 0; index < getComponentCount(); index++) {
4168 Component comp = getComponent(index);
4169 if (comp.isLightweight()) {
4170 if (comp instanceof Container) {
4171 ((Container)comp).recursiveHideHeavyweightChildren();
4172 }
4173 } else {
4174 if (comp.isVisible()) {
4175 if (comp.peer != null) {
4176 comp.peer.setVisible(false);
4177 }
4178 }
4179 }
4180 }
4181 }
4182
4183 private void recursiveRelocateHeavyweightChildren(Point origin) {
4184 for (int index = 0; index < getComponentCount(); index++) {
4185 Component comp = getComponent(index);
4186 if (comp.isLightweight()) {
4187 if (comp instanceof Container &&
4188 ((Container)comp).hasHeavyweightDescendants())
4189 {
4190 final Point newOrigin = new Point(origin);
4191 newOrigin.translate(comp.getX(), comp.getY());
4192 ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
4193 }
4194 } else {
4195 if (comp.peer != null) {
4196 comp.peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
4197 comp.getWidth(), comp.getHeight(),
4198 ComponentPeer.SET_LOCATION);
4199 }
4200 }
4201 }
4202 }
4203
4204 /**
4205 * Checks if the container and its direct lightweight containers are
4206 * visible.
4207 *
4208 * Consider the heavyweight container hides or shows the HW descendants
4209 * automatically. Therefore we care of LW containers' visibility only.
4210 *
4211 * This method MUST be invoked under the TreeLock.
4212 */
4213 final boolean isRecursivelyVisibleUpToHeavyweightContainer() {
4214 if (!isLightweight()) {
4215 return true;
4216 }
4617
4618 if (targetEnter != null) {
4619 retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
4620 }
4621 if (id == MouseEvent.MOUSE_ENTERED) {
4622 // consume native enter event if we generate one
4623 e.consume();
4624 }
4625
4626 targetLastEntered = targetEnter;
4627 }
4628
4629 /*
4630 * Listens to global mouse drag events so even drags originating
4631 * from other heavyweight containers will generate enter/exit
4632 * events in this container
4633 */
4634 private void startListeningForOtherDrags() {
4635 //System.out.println("Adding AWTEventListener");
4636 java.security.AccessController.doPrivileged(
4637 new java.security.PrivilegedAction<Object>() {
4638 public Object run() {
4639 nativeContainer.getToolkit().addAWTEventListener(
4640 LightweightDispatcher.this,
4641 AWTEvent.MOUSE_EVENT_MASK |
4642 AWTEvent.MOUSE_MOTION_EVENT_MASK);
4643 return null;
4644 }
4645 }
4646 );
4647 }
4648
4649 private void stopListeningForOtherDrags() {
4650 //System.out.println("Removing AWTEventListener");
4651 java.security.AccessController.doPrivileged(
4652 new java.security.PrivilegedAction<Object>() {
4653 public Object run() {
4654 nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this);
4655 return null;
4656 }
4657 }
4658 );
4659 }
4660
4661 /*
4662 * (Implementation of AWTEventListener)
4663 * Listen for drag events posted in other hw components so we can
4664 * track enter/exit regardless of where a drag originated
4665 */
4666 public void eventDispatched(AWTEvent e) {
4667 boolean isForeignDrag = (e instanceof MouseEvent) &&
4668 !(e instanceof SunDropTargetEvent) &&
4669 (e.id == MouseEvent.MOUSE_DRAGGED) &&
4670 (e.getSource() != nativeContainer);
4671
4672 if (!isForeignDrag) {
|