181 *
182 * @author Arthur van Hoff
183 * @author Sami Shaio
184 */
185 public abstract class Component implements ImageObserver, MenuContainer,
186 Serializable
187 {
188
189 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component");
190 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component");
191 private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.Component");
192 private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Component");
193
194 /**
195 * The peer of the component. The peer implements the component's
196 * behavior. The peer is set when the <code>Component</code> is
197 * added to a container that also is a peer.
198 * @see #addNotify
199 * @see #removeNotify
200 */
201 transient ComponentPeer peer;
202
203 /**
204 * The parent of the object. It may be <code>null</code>
205 * for top-level components.
206 * @see #getParent
207 */
208 transient Container parent;
209
210 /**
211 * The <code>AppContext</code> of the component. Applets/Plugin may
212 * change the AppContext.
213 */
214 transient AppContext appContext;
215
216 /**
217 * The x position of the component in the parent's coordinate system.
218 *
219 * @serial
220 * @see #getLocation
221 */
907 public void setSize(Component comp, int width, int height) {
908 comp.width = width;
909 comp.height = height;
910 }
911 public Point getLocation(Component comp) {
912 return comp.location_NoClientCode();
913 }
914 public void setLocation(Component comp, int x, int y) {
915 comp.x = x;
916 comp.y = y;
917 }
918 public boolean isEnabled(Component comp) {
919 return comp.isEnabledImpl();
920 }
921 public boolean isDisplayable(Component comp) {
922 return comp.peer != null;
923 }
924 public Cursor getCursor(Component comp) {
925 return comp.getCursor_NoClientCode();
926 }
927 public ComponentPeer getPeer(Component comp) {
928 return comp.peer;
929 }
930 public void setPeer(Component comp, ComponentPeer peer) {
931 comp.peer = peer;
932 }
933 public boolean isLightweight(Component comp) {
934 return (comp.peer instanceof LightweightPeer);
935 }
936 public boolean getIgnoreRepaint(Component comp) {
937 return comp.ignoreRepaint;
938 }
939 public int getWidth(Component comp) {
940 return comp.width;
941 }
942 public int getHeight(Component comp) {
943 return comp.height;
944 }
945 public int getX(Component comp) {
946 return comp.x;
947 }
948 public int getY(Component comp) {
1052 public Container getParent() {
1053 return getParent_NoClientCode();
1054 }
1055
1056 // NOTE: This method may be called by privileged threads.
1057 // This functionality is implemented in a package-private method
1058 // to insure that it cannot be overridden by client subclasses.
1059 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1060 final Container getParent_NoClientCode() {
1061 return parent;
1062 }
1063
1064 // This method is overridden in the Window class to return null,
1065 // because the parent field of the Window object contains
1066 // the owner of the window, not its parent.
1067 Container getContainer() {
1068 return getParent_NoClientCode();
1069 }
1070
1071 /**
1072 * @deprecated As of JDK version 1.1,
1073 * programs should not directly manipulate peers;
1074 * replaced by <code>boolean isDisplayable()</code>.
1075 * @return the peer for this component
1076 */
1077 @Deprecated
1078 public ComponentPeer getPeer() {
1079 return peer;
1080 }
1081
1082 /**
1083 * Associate a <code>DropTarget</code> with this component.
1084 * The <code>Component</code> will receive drops only if it
1085 * is enabled.
1086 *
1087 * @see #isEnabled
1088 * @param dt The DropTarget
1089 */
1090
1091 public synchronized void setDropTarget(DropTarget dt) {
1092 if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))
1093 return;
1094
1095 DropTarget old;
1096
1097 if ((old = dropTarget) != null) {
1098 if (peer != null) dropTarget.removeNotify(peer);
1099
1100 DropTarget t = dropTarget;
1101
1102 dropTarget = null;
1162 }
1163
1164 void setGraphicsConfiguration(GraphicsConfiguration gc) {
1165 synchronized(getTreeLock()) {
1166 if (updateGraphicsData(gc)) {
1167 removeNotify();
1168 addNotify();
1169 }
1170 }
1171 }
1172
1173 boolean updateGraphicsData(GraphicsConfiguration gc) {
1174 checkTreeLock();
1175
1176 if (graphicsConfig == gc) {
1177 return false;
1178 }
1179
1180 graphicsConfig = gc;
1181
1182 ComponentPeer peer = getPeer();
1183 if (peer != null) {
1184 return peer.updateGraphicsData(gc);
1185 }
1186 return false;
1187 }
1188
1189 /**
1190 * Checks that this component's <code>GraphicsDevice</code>
1191 * <code>idString</code> matches the string argument.
1192 */
1193 void checkGD(String stringID) {
1194 if (graphicsConfig != null) {
1195 if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {
1196 throw new IllegalArgumentException(
1197 "adding a container to a container on a different GraphicsDevice");
1198 }
1199 }
1200 }
1201
1202 /**
1264 * a displayable containment hierarchy or when its containment
1265 * hierarchy is made displayable.
1266 * A containment hierarchy is made displayable when its ancestor
1267 * window is either packed or made visible.
1268 * <p>
1269 * A component is made undisplayable either when it is removed from
1270 * a displayable containment hierarchy or when its containment hierarchy
1271 * is made undisplayable. A containment hierarchy is made
1272 * undisplayable when its ancestor window is disposed.
1273 *
1274 * @return <code>true</code> if the component is displayable,
1275 * <code>false</code> otherwise
1276 * @see Container#add(Component)
1277 * @see Window#pack
1278 * @see Window#show
1279 * @see Container#remove(Component)
1280 * @see Window#dispose
1281 * @since 1.2
1282 */
1283 public boolean isDisplayable() {
1284 return getPeer() != null;
1285 }
1286
1287 /**
1288 * Determines whether this component should be visible when its
1289 * parent is visible. Components are
1290 * initially visible, with the exception of top level components such
1291 * as <code>Frame</code> objects.
1292 * @return <code>true</code> if the component is visible,
1293 * <code>false</code> otherwise
1294 * @see #setVisible
1295 * @since 1.0
1296 */
1297 @Transient
1298 public boolean isVisible() {
1299 return isVisible_NoClientCode();
1300 }
1301 final boolean isVisible_NoClientCode() {
1302 return visible;
1303 }
1304
2565 }
2566
2567 /**
2568 * Returns true if this component is completely opaque, returns
2569 * false by default.
2570 * <p>
2571 * An opaque component paints every pixel within its
2572 * rectangular region. A non-opaque component paints only some of
2573 * its pixels, allowing the pixels underneath it to "show through".
2574 * A component that does not fully paint its pixels therefore
2575 * provides a degree of transparency.
2576 * <p>
2577 * Subclasses that guarantee to always completely paint their
2578 * contents should override this method and return true.
2579 *
2580 * @return true if this component is completely opaque
2581 * @see #isLightweight
2582 * @since 1.2
2583 */
2584 public boolean isOpaque() {
2585 if (getPeer() == null) {
2586 return false;
2587 }
2588 else {
2589 return !isLightweight();
2590 }
2591 }
2592
2593
2594 /**
2595 * A lightweight component doesn't have a native toolkit peer.
2596 * Subclasses of <code>Component</code> and <code>Container</code>,
2597 * other than the ones defined in this package like <code>Button</code>
2598 * or <code>Scrollbar</code>, are lightweight.
2599 * All of the Swing components are lightweights.
2600 * <p>
2601 * This method will always return <code>false</code> if this component
2602 * is not displayable because it is impossible to determine the
2603 * weight of an undisplayable component.
2604 *
2605 * @return true if this component has a lightweight peer; false if
2606 * it has a native peer or no peer
2607 * @see #isDisplayable
2608 * @since 1.2
2609 */
2610 public boolean isLightweight() {
2611 return getPeer() instanceof LightweightPeer;
2612 }
2613
2614
2615 /**
2616 * Sets the preferred size of this component to a constant
2617 * value. Subsequent calls to <code>getPreferredSize</code> will always
2618 * return this value. Setting the preferred size to <code>null</code>
2619 * restores the default behavior.
2620 *
2621 * @param preferredSize The new preferred size, or null
2622 * @see #getPreferredSize
2623 * @see #isPreferredSizeSet
2624 * @since 1.5
2625 */
2626 public void setPreferredSize(Dimension preferredSize) {
2627 Dimension old;
2628 // If the preferred size was set, use it as the old value, otherwise
2629 // use null to indicate we didn't previously have a set preferred
2630 // size.
2631 if (prefSizeSet) {
3109 return g;
3110 } else {
3111 return (peer != null) ? peer.getGraphics() : null;
3112 }
3113 }
3114
3115 /**
3116 * Gets the font metrics for the specified font.
3117 * Warning: Since Font metrics are affected by the
3118 * {@link java.awt.font.FontRenderContext FontRenderContext} and
3119 * this method does not provide one, it can return only metrics for
3120 * the default render context which may not match that used when
3121 * rendering on the Component if {@link Graphics2D} functionality is being
3122 * used. Instead metrics can be obtained at rendering time by calling
3123 * {@link Graphics#getFontMetrics()} or text measurement APIs on the
3124 * {@link Font Font} class.
3125 * @param font the font for which font metrics is to be
3126 * obtained
3127 * @return the font metrics for <code>font</code>
3128 * @see #getFont
3129 * @see #getPeer
3130 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
3131 * @see Toolkit#getFontMetrics(Font)
3132 * @since 1.0
3133 */
3134 public FontMetrics getFontMetrics(Font font) {
3135 // This is an unsupported hack, but left in for a customer.
3136 // Do not remove.
3137 FontManager fm = FontManagerFactory.getInstance();
3138 if (fm instanceof SunFontManager
3139 && ((SunFontManager) fm).usePlatformFontMetrics()) {
3140
3141 if (peer != null &&
3142 !(peer instanceof LightweightPeer)) {
3143 return peer.getFontMetrics(font);
3144 }
3145 }
3146 return sun.font.FontDesignMetrics.getMetrics(font);
3147 }
3148
3149 /**
3169 * @see #contains
3170 * @see Toolkit#createCustomCursor
3171 * @see Cursor
3172 * @since 1.1
3173 */
3174 public void setCursor(Cursor cursor) {
3175 this.cursor = cursor;
3176 updateCursorImmediately();
3177 }
3178
3179 /**
3180 * Updates the cursor. May not be invoked from the native
3181 * message pump.
3182 */
3183 final void updateCursorImmediately() {
3184 if (peer instanceof LightweightPeer) {
3185 Container nativeContainer = getNativeContainer();
3186
3187 if (nativeContainer == null) return;
3188
3189 ComponentPeer cPeer = nativeContainer.getPeer();
3190
3191 if (cPeer != null) {
3192 cPeer.updateCursorImmediately();
3193 }
3194 } else if (peer != null) {
3195 peer.updateCursorImmediately();
3196 }
3197 }
3198
3199 /**
3200 * Gets the cursor set in the component. If the component does
3201 * not have a cursor set, the cursor of its parent is returned.
3202 * If no cursor is set in the entire hierarchy,
3203 * <code>Cursor.DEFAULT_CURSOR</code> is returned.
3204 *
3205 * @return the cursor for this component
3206 * @see #setCursor
3207 * @since 1.1
3208 */
3209 public Cursor getCursor() {
4999 break;
5000 }
5001 }
5002 }
5003
5004 /*
5005 * 9. Allow the peer to process the event.
5006 * Except KeyEvents, they will be processed by peer after
5007 * all KeyEventPostProcessors
5008 * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
5009 */
5010 if (!(e instanceof KeyEvent)) {
5011 ComponentPeer tpeer = peer;
5012 if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
5013 // if focus owner is lightweight then its native container
5014 // processes event
5015 Component source = (Component)e.getSource();
5016 if (source != null) {
5017 Container target = source.getNativeContainer();
5018 if (target != null) {
5019 tpeer = target.getPeer();
5020 }
5021 }
5022 }
5023 if (tpeer != null) {
5024 tpeer.handleEvent(e);
5025 }
5026 }
5027 } // dispatchEventImpl()
5028
5029 /*
5030 * If newEventsOnly is false, method is called so that ScrollPane can
5031 * override it and handle common-case mouse wheel scrolling. NOP
5032 * for Component.
5033 */
5034 void autoProcessMouseWheel(MouseWheelEvent e) {}
5035
5036 /*
5037 * Dispatch given MouseWheelEvent to the first ancestor for which
5038 * MouseWheelEvents are enabled.
5039 *
9830 final boolean areBoundsValid() {
9831 Container cont = getContainer();
9832 return cont == null || cont.isValid() || cont.getLayout() == null;
9833 }
9834
9835 /**
9836 * Applies the shape to the component
9837 * @param shape Shape to be applied to the component
9838 */
9839 void applyCompoundShape(Region shape) {
9840 checkTreeLock();
9841
9842 if (!areBoundsValid()) {
9843 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
9844 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9845 }
9846 return;
9847 }
9848
9849 if (!isLightweight()) {
9850 ComponentPeer peer = getPeer();
9851 if (peer != null) {
9852 // The Region class has some optimizations. That's why
9853 // we should manually check whether it's empty and
9854 // substitute the object ourselves. Otherwise we end up
9855 // with some incorrect Region object with loX being
9856 // greater than the hiX for instance.
9857 if (shape.isEmpty()) {
9858 shape = Region.EMPTY_REGION;
9859 }
9860
9861
9862 // Note: the shape is not really copied/cloned. We create
9863 // the Region object ourselves, so there's no any possibility
9864 // to modify the object outside of the mixing code.
9865 // Nullifying compoundShape means that the component has normal shape
9866 // (or has no shape at all).
9867 if (shape.equals(getNormalShape())) {
9868 if (this.compoundShape == null) {
9869 return;
9870 }
9954 Container parent = getContainer();
9955 if (parent == null) {
9956 return -1;
9957 }
9958
9959 int nextAbove = parent.getComponentZOrder(this) - 1;
9960
9961 return nextAbove < 0 ? -1 : nextAbove;
9962 }
9963
9964 final ComponentPeer getHWPeerAboveMe() {
9965 checkTreeLock();
9966
9967 Container cont = getContainer();
9968 int indexAbove = getSiblingIndexAbove();
9969
9970 while (cont != null) {
9971 for (int i = indexAbove; i > -1; i--) {
9972 Component comp = cont.getComponent(i);
9973 if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
9974 return comp.getPeer();
9975 }
9976 }
9977 // traversing the hierarchy up to the closest HW container;
9978 // further traversing may return a component that is not actually
9979 // a native sibling of this component and this kind of z-order
9980 // request may not be allowed by the underlying system (6852051).
9981 if (!cont.isLightweight()) {
9982 break;
9983 }
9984
9985 indexAbove = cont.getSiblingIndexAbove();
9986 cont = cont.getContainer();
9987 }
9988
9989 return null;
9990 }
9991
9992 final int getSiblingIndexBelow() {
9993 checkTreeLock();
9994 Container parent = getContainer();
|
181 *
182 * @author Arthur van Hoff
183 * @author Sami Shaio
184 */
185 public abstract class Component implements ImageObserver, MenuContainer,
186 Serializable
187 {
188
189 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component");
190 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component");
191 private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.Component");
192 private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Component");
193
194 /**
195 * The peer of the component. The peer implements the component's
196 * behavior. The peer is set when the <code>Component</code> is
197 * added to a container that also is a peer.
198 * @see #addNotify
199 * @see #removeNotify
200 */
201 transient volatile ComponentPeer peer;
202
203 /**
204 * The parent of the object. It may be <code>null</code>
205 * for top-level components.
206 * @see #getParent
207 */
208 transient Container parent;
209
210 /**
211 * The <code>AppContext</code> of the component. Applets/Plugin may
212 * change the AppContext.
213 */
214 transient AppContext appContext;
215
216 /**
217 * The x position of the component in the parent's coordinate system.
218 *
219 * @serial
220 * @see #getLocation
221 */
907 public void setSize(Component comp, int width, int height) {
908 comp.width = width;
909 comp.height = height;
910 }
911 public Point getLocation(Component comp) {
912 return comp.location_NoClientCode();
913 }
914 public void setLocation(Component comp, int x, int y) {
915 comp.x = x;
916 comp.y = y;
917 }
918 public boolean isEnabled(Component comp) {
919 return comp.isEnabledImpl();
920 }
921 public boolean isDisplayable(Component comp) {
922 return comp.peer != null;
923 }
924 public Cursor getCursor(Component comp) {
925 return comp.getCursor_NoClientCode();
926 }
927 @SuppressWarnings("unchecked")
928 public <T extends ComponentPeer> T getPeer(Component comp) {
929 return (T) comp.peer;
930 }
931 public void setPeer(Component comp, ComponentPeer peer) {
932 comp.peer = peer;
933 }
934 public boolean isLightweight(Component comp) {
935 return (comp.peer instanceof LightweightPeer);
936 }
937 public boolean getIgnoreRepaint(Component comp) {
938 return comp.ignoreRepaint;
939 }
940 public int getWidth(Component comp) {
941 return comp.width;
942 }
943 public int getHeight(Component comp) {
944 return comp.height;
945 }
946 public int getX(Component comp) {
947 return comp.x;
948 }
949 public int getY(Component comp) {
1053 public Container getParent() {
1054 return getParent_NoClientCode();
1055 }
1056
1057 // NOTE: This method may be called by privileged threads.
1058 // This functionality is implemented in a package-private method
1059 // to insure that it cannot be overridden by client subclasses.
1060 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1061 final Container getParent_NoClientCode() {
1062 return parent;
1063 }
1064
1065 // This method is overridden in the Window class to return null,
1066 // because the parent field of the Window object contains
1067 // the owner of the window, not its parent.
1068 Container getContainer() {
1069 return getParent_NoClientCode();
1070 }
1071
1072 /**
1073 * Associate a <code>DropTarget</code> with this component.
1074 * The <code>Component</code> will receive drops only if it
1075 * is enabled.
1076 *
1077 * @see #isEnabled
1078 * @param dt The DropTarget
1079 */
1080
1081 public synchronized void setDropTarget(DropTarget dt) {
1082 if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))
1083 return;
1084
1085 DropTarget old;
1086
1087 if ((old = dropTarget) != null) {
1088 if (peer != null) dropTarget.removeNotify(peer);
1089
1090 DropTarget t = dropTarget;
1091
1092 dropTarget = null;
1152 }
1153
1154 void setGraphicsConfiguration(GraphicsConfiguration gc) {
1155 synchronized(getTreeLock()) {
1156 if (updateGraphicsData(gc)) {
1157 removeNotify();
1158 addNotify();
1159 }
1160 }
1161 }
1162
1163 boolean updateGraphicsData(GraphicsConfiguration gc) {
1164 checkTreeLock();
1165
1166 if (graphicsConfig == gc) {
1167 return false;
1168 }
1169
1170 graphicsConfig = gc;
1171
1172 ComponentPeer peer = this.peer;
1173 if (peer != null) {
1174 return peer.updateGraphicsData(gc);
1175 }
1176 return false;
1177 }
1178
1179 /**
1180 * Checks that this component's <code>GraphicsDevice</code>
1181 * <code>idString</code> matches the string argument.
1182 */
1183 void checkGD(String stringID) {
1184 if (graphicsConfig != null) {
1185 if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {
1186 throw new IllegalArgumentException(
1187 "adding a container to a container on a different GraphicsDevice");
1188 }
1189 }
1190 }
1191
1192 /**
1254 * a displayable containment hierarchy or when its containment
1255 * hierarchy is made displayable.
1256 * A containment hierarchy is made displayable when its ancestor
1257 * window is either packed or made visible.
1258 * <p>
1259 * A component is made undisplayable either when it is removed from
1260 * a displayable containment hierarchy or when its containment hierarchy
1261 * is made undisplayable. A containment hierarchy is made
1262 * undisplayable when its ancestor window is disposed.
1263 *
1264 * @return <code>true</code> if the component is displayable,
1265 * <code>false</code> otherwise
1266 * @see Container#add(Component)
1267 * @see Window#pack
1268 * @see Window#show
1269 * @see Container#remove(Component)
1270 * @see Window#dispose
1271 * @since 1.2
1272 */
1273 public boolean isDisplayable() {
1274 return peer != null;
1275 }
1276
1277 /**
1278 * Determines whether this component should be visible when its
1279 * parent is visible. Components are
1280 * initially visible, with the exception of top level components such
1281 * as <code>Frame</code> objects.
1282 * @return <code>true</code> if the component is visible,
1283 * <code>false</code> otherwise
1284 * @see #setVisible
1285 * @since 1.0
1286 */
1287 @Transient
1288 public boolean isVisible() {
1289 return isVisible_NoClientCode();
1290 }
1291 final boolean isVisible_NoClientCode() {
1292 return visible;
1293 }
1294
2555 }
2556
2557 /**
2558 * Returns true if this component is completely opaque, returns
2559 * false by default.
2560 * <p>
2561 * An opaque component paints every pixel within its
2562 * rectangular region. A non-opaque component paints only some of
2563 * its pixels, allowing the pixels underneath it to "show through".
2564 * A component that does not fully paint its pixels therefore
2565 * provides a degree of transparency.
2566 * <p>
2567 * Subclasses that guarantee to always completely paint their
2568 * contents should override this method and return true.
2569 *
2570 * @return true if this component is completely opaque
2571 * @see #isLightweight
2572 * @since 1.2
2573 */
2574 public boolean isOpaque() {
2575 if (peer == null) {
2576 return false;
2577 }
2578 else {
2579 return !isLightweight();
2580 }
2581 }
2582
2583
2584 /**
2585 * A lightweight component doesn't have a native toolkit peer.
2586 * Subclasses of <code>Component</code> and <code>Container</code>,
2587 * other than the ones defined in this package like <code>Button</code>
2588 * or <code>Scrollbar</code>, are lightweight.
2589 * All of the Swing components are lightweights.
2590 * <p>
2591 * This method will always return <code>false</code> if this component
2592 * is not displayable because it is impossible to determine the
2593 * weight of an undisplayable component.
2594 *
2595 * @return true if this component has a lightweight peer; false if
2596 * it has a native peer or no peer
2597 * @see #isDisplayable
2598 * @since 1.2
2599 */
2600 public boolean isLightweight() {
2601 return peer instanceof LightweightPeer;
2602 }
2603
2604
2605 /**
2606 * Sets the preferred size of this component to a constant
2607 * value. Subsequent calls to <code>getPreferredSize</code> will always
2608 * return this value. Setting the preferred size to <code>null</code>
2609 * restores the default behavior.
2610 *
2611 * @param preferredSize The new preferred size, or null
2612 * @see #getPreferredSize
2613 * @see #isPreferredSizeSet
2614 * @since 1.5
2615 */
2616 public void setPreferredSize(Dimension preferredSize) {
2617 Dimension old;
2618 // If the preferred size was set, use it as the old value, otherwise
2619 // use null to indicate we didn't previously have a set preferred
2620 // size.
2621 if (prefSizeSet) {
3099 return g;
3100 } else {
3101 return (peer != null) ? peer.getGraphics() : null;
3102 }
3103 }
3104
3105 /**
3106 * Gets the font metrics for the specified font.
3107 * Warning: Since Font metrics are affected by the
3108 * {@link java.awt.font.FontRenderContext FontRenderContext} and
3109 * this method does not provide one, it can return only metrics for
3110 * the default render context which may not match that used when
3111 * rendering on the Component if {@link Graphics2D} functionality is being
3112 * used. Instead metrics can be obtained at rendering time by calling
3113 * {@link Graphics#getFontMetrics()} or text measurement APIs on the
3114 * {@link Font Font} class.
3115 * @param font the font for which font metrics is to be
3116 * obtained
3117 * @return the font metrics for <code>font</code>
3118 * @see #getFont
3119 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
3120 * @see Toolkit#getFontMetrics(Font)
3121 * @since 1.0
3122 */
3123 public FontMetrics getFontMetrics(Font font) {
3124 // This is an unsupported hack, but left in for a customer.
3125 // Do not remove.
3126 FontManager fm = FontManagerFactory.getInstance();
3127 if (fm instanceof SunFontManager
3128 && ((SunFontManager) fm).usePlatformFontMetrics()) {
3129
3130 if (peer != null &&
3131 !(peer instanceof LightweightPeer)) {
3132 return peer.getFontMetrics(font);
3133 }
3134 }
3135 return sun.font.FontDesignMetrics.getMetrics(font);
3136 }
3137
3138 /**
3158 * @see #contains
3159 * @see Toolkit#createCustomCursor
3160 * @see Cursor
3161 * @since 1.1
3162 */
3163 public void setCursor(Cursor cursor) {
3164 this.cursor = cursor;
3165 updateCursorImmediately();
3166 }
3167
3168 /**
3169 * Updates the cursor. May not be invoked from the native
3170 * message pump.
3171 */
3172 final void updateCursorImmediately() {
3173 if (peer instanceof LightweightPeer) {
3174 Container nativeContainer = getNativeContainer();
3175
3176 if (nativeContainer == null) return;
3177
3178 ComponentPeer cPeer = nativeContainer.peer;
3179
3180 if (cPeer != null) {
3181 cPeer.updateCursorImmediately();
3182 }
3183 } else if (peer != null) {
3184 peer.updateCursorImmediately();
3185 }
3186 }
3187
3188 /**
3189 * Gets the cursor set in the component. If the component does
3190 * not have a cursor set, the cursor of its parent is returned.
3191 * If no cursor is set in the entire hierarchy,
3192 * <code>Cursor.DEFAULT_CURSOR</code> is returned.
3193 *
3194 * @return the cursor for this component
3195 * @see #setCursor
3196 * @since 1.1
3197 */
3198 public Cursor getCursor() {
4988 break;
4989 }
4990 }
4991 }
4992
4993 /*
4994 * 9. Allow the peer to process the event.
4995 * Except KeyEvents, they will be processed by peer after
4996 * all KeyEventPostProcessors
4997 * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
4998 */
4999 if (!(e instanceof KeyEvent)) {
5000 ComponentPeer tpeer = peer;
5001 if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
5002 // if focus owner is lightweight then its native container
5003 // processes event
5004 Component source = (Component)e.getSource();
5005 if (source != null) {
5006 Container target = source.getNativeContainer();
5007 if (target != null) {
5008 tpeer = target.peer;
5009 }
5010 }
5011 }
5012 if (tpeer != null) {
5013 tpeer.handleEvent(e);
5014 }
5015 }
5016 } // dispatchEventImpl()
5017
5018 /*
5019 * If newEventsOnly is false, method is called so that ScrollPane can
5020 * override it and handle common-case mouse wheel scrolling. NOP
5021 * for Component.
5022 */
5023 void autoProcessMouseWheel(MouseWheelEvent e) {}
5024
5025 /*
5026 * Dispatch given MouseWheelEvent to the first ancestor for which
5027 * MouseWheelEvents are enabled.
5028 *
9819 final boolean areBoundsValid() {
9820 Container cont = getContainer();
9821 return cont == null || cont.isValid() || cont.getLayout() == null;
9822 }
9823
9824 /**
9825 * Applies the shape to the component
9826 * @param shape Shape to be applied to the component
9827 */
9828 void applyCompoundShape(Region shape) {
9829 checkTreeLock();
9830
9831 if (!areBoundsValid()) {
9832 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
9833 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9834 }
9835 return;
9836 }
9837
9838 if (!isLightweight()) {
9839 ComponentPeer peer = this.peer;
9840 if (peer != null) {
9841 // The Region class has some optimizations. That's why
9842 // we should manually check whether it's empty and
9843 // substitute the object ourselves. Otherwise we end up
9844 // with some incorrect Region object with loX being
9845 // greater than the hiX for instance.
9846 if (shape.isEmpty()) {
9847 shape = Region.EMPTY_REGION;
9848 }
9849
9850
9851 // Note: the shape is not really copied/cloned. We create
9852 // the Region object ourselves, so there's no any possibility
9853 // to modify the object outside of the mixing code.
9854 // Nullifying compoundShape means that the component has normal shape
9855 // (or has no shape at all).
9856 if (shape.equals(getNormalShape())) {
9857 if (this.compoundShape == null) {
9858 return;
9859 }
9943 Container parent = getContainer();
9944 if (parent == null) {
9945 return -1;
9946 }
9947
9948 int nextAbove = parent.getComponentZOrder(this) - 1;
9949
9950 return nextAbove < 0 ? -1 : nextAbove;
9951 }
9952
9953 final ComponentPeer getHWPeerAboveMe() {
9954 checkTreeLock();
9955
9956 Container cont = getContainer();
9957 int indexAbove = getSiblingIndexAbove();
9958
9959 while (cont != null) {
9960 for (int i = indexAbove; i > -1; i--) {
9961 Component comp = cont.getComponent(i);
9962 if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
9963 return comp.peer;
9964 }
9965 }
9966 // traversing the hierarchy up to the closest HW container;
9967 // further traversing may return a component that is not actually
9968 // a native sibling of this component and this kind of z-order
9969 // request may not be allowed by the underlying system (6852051).
9970 if (!cont.isLightweight()) {
9971 break;
9972 }
9973
9974 indexAbove = cont.getSiblingIndexAbove();
9975 cont = cont.getContainer();
9976 }
9977
9978 return null;
9979 }
9980
9981 final int getSiblingIndexBelow() {
9982 checkTreeLock();
9983 Container parent = getContainer();
|