1 /*
   2  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.Component;
  29 import java.awt.Container;
  30 import java.awt.AWTEvent;
  31 import java.awt.Font;
  32 import java.awt.Color;
  33 import java.awt.Cursor;
  34 import java.awt.Point;
  35 
  36 import java.awt.peer.ComponentPeer;
  37 
  38 import java.lang.reflect.Field;
  39 import java.lang.reflect.Method;
  40 import java.lang.reflect.InvocationTargetException;
  41 
  42 import java.util.logging.Logger;
  43 import java.util.logging.Level;
  44 
  45 import java.security.AccessController;
  46 import java.security.PrivilegedAction;
  47 
  48 /**
  49  * A collection of methods for modifying package private fields in AWT components.
  50  * This class is meant to be used by Peer code only. Previously peer code
  51  * got around this problem by modifying fields from native code. However
  52  * as we move away from native code to Pure-java peers we need this class.
  53  *
  54  * @author Bino George
  55  */
  56 
  57 
  58 public class ComponentAccessor
  59 {
  60     private static Class componentClass;
  61     private static Field fieldX;
  62     private static Field fieldY;
  63     private static Field fieldWidth;
  64     private static Field fieldHeight;
  65     private static Method methodGetParentNoClientCode;
  66     private static Method methodGetFontNoClientCode;
  67     private static Method methodProcessEvent;
  68     private static Method methodEnableEvents;
  69     private static Field fieldParent;
  70     private static Field fieldBackground;
  71     private static Field fieldForeground;
  72     private static Field fieldFont;
  73     private static Field fieldIgnoreRepaint;
  74     private static Field fieldPeer;
  75     private static Field fieldVisible;
  76     private static Method methodIsEnabledImpl;
  77     private static Method methodGetCursorNoClientCode;
  78     private static Method methodLocationNoClientCode;
  79 
  80     private static final Logger log = Logger.getLogger("sun.awt.ComponentAccessor");
  81 
  82     private ComponentAccessor() {
  83     }
  84 
  85     static {
  86         AccessController.doPrivileged( new PrivilegedAction() {
  87                 public Object run() {
  88                     try {
  89                         componentClass = Class.forName("java.awt.Component");
  90                         fieldX  = componentClass.getDeclaredField("x");
  91                         fieldX.setAccessible(true);
  92                         fieldY  = componentClass.getDeclaredField("y");
  93                         fieldY.setAccessible(true);
  94                         fieldWidth  = componentClass.getDeclaredField("width");
  95                         fieldWidth.setAccessible(true);
  96                         fieldHeight  = componentClass.getDeclaredField("height");
  97                         fieldHeight.setAccessible(true);
  98                         fieldForeground  = componentClass.getDeclaredField("foreground");
  99                         fieldForeground.setAccessible(true);
 100                         fieldBackground  = componentClass.getDeclaredField("background");
 101                         fieldBackground.setAccessible(true);
 102                         fieldFont = componentClass.getDeclaredField("font");
 103                         fieldFont.setAccessible(true);
 104                         methodGetParentNoClientCode = componentClass.getDeclaredMethod("getParent_NoClientCode", (Class[]) null);
 105                         methodGetParentNoClientCode.setAccessible(true);
 106                         methodGetFontNoClientCode = componentClass.getDeclaredMethod("getFont_NoClientCode", (Class[]) null);
 107                         methodGetFontNoClientCode.setAccessible(true);
 108                         Class[] argTypes = { AWTEvent.class };
 109                         methodProcessEvent = componentClass.getDeclaredMethod("processEvent",argTypes);
 110                         methodProcessEvent.setAccessible(true);
 111                         Class[] argTypesForMethodEnableEvents = { Long.TYPE };
 112                         methodEnableEvents = componentClass.getDeclaredMethod("enableEvents",argTypesForMethodEnableEvents);
 113                         methodEnableEvents.setAccessible(true);
 114 
 115                         fieldParent  = componentClass.getDeclaredField("parent");
 116                         fieldParent.setAccessible(true);
 117                         fieldIgnoreRepaint = componentClass.getDeclaredField("ignoreRepaint");
 118                         fieldIgnoreRepaint.setAccessible(true);
 119 
 120                         fieldPeer = componentClass.getDeclaredField("peer");
 121                         fieldPeer.setAccessible(true);
 122 
 123                         fieldVisible = componentClass.getDeclaredField("visible");
 124                         fieldVisible.setAccessible(true);
 125 
 126                         methodIsEnabledImpl = componentClass.getDeclaredMethod("isEnabledImpl", (Class[]) null);
 127                         methodIsEnabledImpl.setAccessible(true);
 128 
 129                         methodGetCursorNoClientCode = componentClass.getDeclaredMethod("getCursor_NoClientCode", (Class[]) null);
 130                         methodGetCursorNoClientCode.setAccessible(true);
 131 
 132                         methodLocationNoClientCode = componentClass.getDeclaredMethod("location_NoClientCode", (Class[]) null);
 133                         methodLocationNoClientCode.setAccessible(true);
 134                     }
 135                     catch (NoSuchFieldException e) {
 136                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 137                     }
 138                     catch (ClassNotFoundException e) {
 139                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 140                     }
 141                     catch (NoSuchMethodException e) {
 142                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 143                     }
 144                     // to please javac
 145                     return null;
 146                 }
 147             });
 148     }
 149 
 150     public static void setX(Component c, int x)
 151     {
 152         try {
 153             fieldX.setInt(c,x);
 154         }
 155         catch (IllegalAccessException e)
 156         {
 157             log.log(Level.FINE, "Unable to access the Component object", e);
 158         }
 159     }
 160 
 161     public static void setY(Component c, int y)
 162     {
 163         try {
 164             fieldY.setInt(c,y);
 165         }
 166         catch (IllegalAccessException e)
 167         {
 168             log.log(Level.FINE, "Unable to access the Component object", e);
 169         }
 170     }
 171 
 172     public static void setWidth(Component c, int width)
 173     {
 174         try {
 175             fieldWidth.setInt(c,width);
 176         }
 177         catch (IllegalAccessException e)
 178         {
 179             log.log(Level.FINE, "Unable to access the Component object", e);
 180         }
 181     }
 182 
 183     public static void setHeight(Component c, int height)
 184     {
 185         try {
 186             fieldHeight.setInt(c,height);
 187         }
 188         catch (IllegalAccessException e)
 189         {
 190             log.log(Level.FINE, "Unable to access the Component object", e);
 191         }
 192     }
 193 
 194     public static void setBounds(Component c, int x, int y, int width, int height)
 195     {
 196         try {
 197             fieldX.setInt(c,x);
 198             fieldY.setInt(c,y);
 199             fieldWidth.setInt(c,width);
 200             fieldHeight.setInt(c,height);
 201         }
 202         catch (IllegalAccessException e)
 203         {
 204             log.log(Level.FINE, "Unable to access the Component object", e);
 205         }
 206     }
 207 
 208     public static int getX(Component c) {
 209         try {
 210             return fieldX.getInt(c);
 211         }
 212         catch (IllegalAccessException e)
 213         {
 214             log.log(Level.FINE, "Unable to access the Component object", e);
 215         }
 216         return 0;
 217     }
 218 
 219     public static int getY(Component c) {
 220         try {
 221             return fieldY.getInt(c);
 222         }
 223         catch (IllegalAccessException e)
 224         {
 225             log.log(Level.FINE, "Unable to access the Component object", e);
 226         }
 227         return 0;
 228     }
 229 
 230     public static int getWidth(Component c) {
 231         try {
 232             return fieldWidth.getInt(c);
 233         }
 234         catch (IllegalAccessException e)
 235         {
 236             log.log(Level.FINE, "Unable to access the Component object", e);
 237         }
 238         return 0;
 239     }
 240 
 241     public static int getHeight(Component c) {
 242         try {
 243             return fieldHeight.getInt(c);
 244         }
 245         catch (IllegalAccessException e)
 246         {
 247             log.log(Level.FINE, "Unable to access the Component object", e);
 248         }
 249         return 0;
 250     }
 251 
 252     public static Container getParent_NoClientCode(Component c) {
 253         Container parent=null;
 254 
 255         try {
 256             parent = (Container) methodGetParentNoClientCode.invoke(c, (Object[]) null);
 257         }
 258         catch (IllegalAccessException e)
 259         {
 260             log.log(Level.FINE, "Unable to access the Component object", e);
 261         }
 262         catch (InvocationTargetException e) {
 263             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 264         }
 265 
 266         return parent;
 267     }
 268 
 269     public static Font getFont_NoClientCode(Component c) {
 270         Font font=null;
 271 
 272         try {
 273             font = (Font) methodGetFontNoClientCode.invoke(c, (Object[]) null);
 274         }
 275         catch (IllegalAccessException e)
 276         {
 277             log.log(Level.FINE, "Unable to access the Component object", e);
 278         }
 279         catch (InvocationTargetException e) {
 280             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 281         }
 282 
 283         return font;
 284     }
 285 
 286     public static void processEvent(Component c, AWTEvent event) {
 287         Font font=null;
 288 
 289         try {
 290             Object[] args = new Object[1];
 291             args[0] = event;
 292             methodProcessEvent.invoke(c,args);
 293         }
 294         catch (IllegalAccessException e)
 295         {
 296             log.log(Level.FINE, "Unable to access the Component object", e);
 297         }
 298         catch (InvocationTargetException e) {
 299             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 300         }
 301     }
 302 
 303     public static void enableEvents(Component c, long event_mask) {
 304         try {
 305             Object[] args = new Object[1];
 306             args[0] = Long.valueOf(event_mask);
 307             methodEnableEvents.invoke(c,args);
 308         }
 309         catch (IllegalAccessException e)
 310         {
 311             log.log(Level.FINE, "Unable to access the Component object", e);
 312         }
 313         catch (InvocationTargetException e) {
 314             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 315         }
 316     }
 317 
 318     public static void setParent(Component c, Container parent)
 319     {
 320         try {
 321             fieldParent.set(c,parent);
 322         }
 323         catch (IllegalAccessException e)
 324         {
 325             log.log(Level.FINE, "Unable to access the Component object", e);
 326         }
 327     }
 328 
 329     public static Color getForeground(Component c)
 330     {
 331         Color color = null;
 332         try {
 333             color = (Color) fieldForeground.get(c);
 334         }
 335         catch (IllegalAccessException e)
 336         {
 337             log.log(Level.FINE, "Unable to access the Component object", e);
 338         }
 339         return color;
 340     }
 341 
 342     public static Color getBackground(Component c)
 343     {
 344         Color color = null;
 345         try {
 346             color = (Color) fieldBackground.get(c);
 347         }
 348         catch (IllegalAccessException e)
 349         {
 350             log.log(Level.FINE, "Unable to access the Component object", e);
 351         }
 352         return color;
 353     }
 354 
 355     public static void setBackground(Component c, Color color) {
 356         try {
 357             fieldBackground.set(c, color);
 358         }
 359         catch (IllegalAccessException e)
 360         {
 361             log.log(Level.FINE, "Unable to access the Component object", e);
 362         }
 363     }
 364 
 365     public static Font getFont(Component c)
 366     {
 367         Font f = null;
 368         try {
 369             f = (Font) fieldFont.get(c);
 370         }
 371         catch (IllegalAccessException e)
 372         {
 373             log.log(Level.FINE, "Unable to access the Component object", e);
 374         }
 375         return f;
 376     }
 377 
 378     public static ComponentPeer getPeer(Component c) {
 379         ComponentPeer peer = null;
 380         try {
 381             peer = (ComponentPeer)fieldPeer.get(c);
 382         }
 383         catch (IllegalAccessException e)
 384         {
 385             log.log(Level.FINE, "Unable to access the Component object", e);
 386         }
 387         return peer;
 388     }
 389 
 390     public static void setPeer(Component c, ComponentPeer peer) {
 391         try {
 392             fieldPeer.set(c, peer);
 393         } catch (IllegalAccessException e)
 394         {
 395             log.log(Level.FINE, "Unable to access the Component object", e);
 396         }
 397     }
 398 
 399     public static boolean getIgnoreRepaint(Component comp) {
 400         try {
 401             return fieldIgnoreRepaint.getBoolean(comp);
 402         }
 403         catch (IllegalAccessException e) {
 404             log.log(Level.FINE, "Unable to access the Component object", e);
 405         }
 406 
 407         return false;
 408     }
 409 
 410     public static boolean getVisible(Component c) {
 411         try {
 412             return fieldVisible.getBoolean(c);
 413         }
 414         catch (IllegalAccessException e)
 415         {
 416             log.log(Level.FINE, "Unable to access the Component object", e);
 417         }
 418         return false;
 419     }
 420 
 421     public static boolean isEnabledImpl(Component c) {
 422         boolean enabled = true;
 423         try {
 424             enabled = (Boolean) methodIsEnabledImpl.invoke(c, (Object[]) null);
 425         }
 426         catch (IllegalAccessException e)
 427         {
 428             log.log(Level.FINE, "Unable to access the Component object", e);
 429         }
 430         catch (InvocationTargetException e) {
 431             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 432         }
 433         return enabled;
 434     }
 435 
 436     public static Cursor getCursor_NoClientCode(Component c) {
 437         Cursor cursor = null;
 438 
 439         try {
 440             cursor = (Cursor) methodGetCursorNoClientCode.invoke(c, (Object[]) null);
 441         }
 442         catch (IllegalAccessException e)
 443         {
 444             log.log(Level.FINE, "Unable to access the Component object", e);
 445         }
 446         catch (InvocationTargetException e) {
 447             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 448         }
 449 
 450         return cursor;
 451     }
 452 
 453     public static Point getLocation_NoClientCode(Component c) {
 454         Point loc = null;
 455 
 456         try {
 457             loc = (Point) methodLocationNoClientCode.invoke(c, (Object[]) null);
 458         }
 459         catch (IllegalAccessException e)
 460         {
 461             log.log(Level.FINE, "Unable to access the Component object", e);
 462         }
 463         catch (InvocationTargetException e) {
 464             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 465         }
 466 
 467         return loc;
 468     }
 469 }