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 fieldPacked;
  74     private static Field fieldIgnoreRepaint;
  75     private static Field fieldPeer;
  76     private static Field fieldVisible;
  77     private static Method methodIsEnabledImpl;
  78     private static Method methodGetCursorNoClientCode;
  79     private static Method methodLocationNoClientCode;
  80 
  81     private static final Logger log = Logger.getLogger("sun.awt.ComponentAccessor");
  82 
  83     private ComponentAccessor() {
  84     }
  85 
  86     static {
  87         AccessController.doPrivileged( new PrivilegedAction() {
  88                 public Object run() {
  89                     try {
  90                         componentClass = Class.forName("java.awt.Component");
  91                         fieldX  = componentClass.getDeclaredField("x");
  92                         fieldX.setAccessible(true);
  93                         fieldY  = componentClass.getDeclaredField("y");
  94                         fieldY.setAccessible(true);
  95                         fieldWidth  = componentClass.getDeclaredField("width");
  96                         fieldWidth.setAccessible(true);
  97                         fieldHeight  = componentClass.getDeclaredField("height");
  98                         fieldHeight.setAccessible(true);
  99                         fieldForeground  = componentClass.getDeclaredField("foreground");
 100                         fieldForeground.setAccessible(true);
 101                         fieldBackground  = componentClass.getDeclaredField("background");
 102                         fieldBackground.setAccessible(true);
 103                         fieldFont = componentClass.getDeclaredField("font");
 104                         fieldFont.setAccessible(true);
 105                         methodGetParentNoClientCode = componentClass.getDeclaredMethod("getParent_NoClientCode", (Class[]) null);
 106                         methodGetParentNoClientCode.setAccessible(true);
 107                         methodGetFontNoClientCode = componentClass.getDeclaredMethod("getFont_NoClientCode", (Class[]) null);
 108                         methodGetFontNoClientCode.setAccessible(true);
 109                         Class[] argTypes = { AWTEvent.class };
 110                         methodProcessEvent = componentClass.getDeclaredMethod("processEvent",argTypes);
 111                         methodProcessEvent.setAccessible(true);
 112                         Class[] argTypesForMethodEnableEvents = { Long.TYPE };
 113                         methodEnableEvents = componentClass.getDeclaredMethod("enableEvents",argTypesForMethodEnableEvents);
 114                         methodEnableEvents.setAccessible(true);
 115 
 116                         fieldParent  = componentClass.getDeclaredField("parent");
 117                         fieldParent.setAccessible(true);
 118                         fieldPacked = componentClass.getDeclaredField("isPacked");
 119                         fieldPacked.setAccessible(true);
 120                         fieldIgnoreRepaint = componentClass.getDeclaredField("ignoreRepaint");
 121                         fieldIgnoreRepaint.setAccessible(true);
 122 
 123                         fieldPeer = componentClass.getDeclaredField("peer");
 124                         fieldPeer.setAccessible(true);
 125 
 126                         fieldVisible = componentClass.getDeclaredField("visible");
 127                         fieldVisible.setAccessible(true);
 128 
 129                         methodIsEnabledImpl = componentClass.getDeclaredMethod("isEnabledImpl", (Class[]) null);
 130                         methodIsEnabledImpl.setAccessible(true);
 131 
 132                         methodGetCursorNoClientCode = componentClass.getDeclaredMethod("getCursor_NoClientCode", (Class[]) null);
 133                         methodGetCursorNoClientCode.setAccessible(true);
 134 
 135                         methodLocationNoClientCode = componentClass.getDeclaredMethod("location_NoClientCode", (Class[]) null);
 136                         methodLocationNoClientCode.setAccessible(true);
 137                     }
 138                     catch (NoSuchFieldException e) {
 139                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 140                     }
 141                     catch (ClassNotFoundException e) {
 142                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 143                     }
 144                     catch (NoSuchMethodException e) {
 145                         log.log(Level.FINE, "Unable to initialize ComponentAccessor", e);
 146                     }
 147                     // to please javac
 148                     return null;
 149                 }
 150             });
 151     }
 152 
 153     public static void setX(Component c, int x)
 154     {
 155         try {
 156             fieldX.setInt(c,x);
 157         }
 158         catch (IllegalAccessException e)
 159         {
 160             log.log(Level.FINE, "Unable to access the Component object", e);
 161         }
 162     }
 163 
 164     public static void setY(Component c, int y)
 165     {
 166         try {
 167             fieldY.setInt(c,y);
 168         }
 169         catch (IllegalAccessException e)
 170         {
 171             log.log(Level.FINE, "Unable to access the Component object", e);
 172         }
 173     }
 174 
 175     public static void setWidth(Component c, int width)
 176     {
 177         try {
 178             fieldWidth.setInt(c,width);
 179         }
 180         catch (IllegalAccessException e)
 181         {
 182             log.log(Level.FINE, "Unable to access the Component object", e);
 183         }
 184     }
 185 
 186     public static void setHeight(Component c, int height)
 187     {
 188         try {
 189             fieldHeight.setInt(c,height);
 190         }
 191         catch (IllegalAccessException e)
 192         {
 193             log.log(Level.FINE, "Unable to access the Component object", e);
 194         }
 195     }
 196 
 197     public static void setBounds(Component c, int x, int y, int width, int height)
 198     {
 199         try {
 200             fieldX.setInt(c,x);
 201             fieldY.setInt(c,y);
 202             fieldWidth.setInt(c,width);
 203             fieldHeight.setInt(c,height);
 204         }
 205         catch (IllegalAccessException e)
 206         {
 207             log.log(Level.FINE, "Unable to access the Component object", e);
 208         }
 209     }
 210 
 211     public static int getX(Component c) {
 212         try {
 213             return fieldX.getInt(c);
 214         }
 215         catch (IllegalAccessException e)
 216         {
 217             log.log(Level.FINE, "Unable to access the Component object", e);
 218         }
 219         return 0;
 220     }
 221 
 222     public static int getY(Component c) {
 223         try {
 224             return fieldY.getInt(c);
 225         }
 226         catch (IllegalAccessException e)
 227         {
 228             log.log(Level.FINE, "Unable to access the Component object", e);
 229         }
 230         return 0;
 231     }
 232 
 233     public static int getWidth(Component c) {
 234         try {
 235             return fieldWidth.getInt(c);
 236         }
 237         catch (IllegalAccessException e)
 238         {
 239             log.log(Level.FINE, "Unable to access the Component object", e);
 240         }
 241         return 0;
 242     }
 243 
 244     public static int getHeight(Component c) {
 245         try {
 246             return fieldHeight.getInt(c);
 247         }
 248         catch (IllegalAccessException e)
 249         {
 250             log.log(Level.FINE, "Unable to access the Component object", e);
 251         }
 252         return 0;
 253     }
 254 
 255     public static boolean getIsPacked(Component c) {
 256         try {
 257             return fieldPacked.getBoolean(c);
 258         }
 259         catch (IllegalAccessException e)
 260         {
 261             log.log(Level.FINE, "Unable to access the Component object", e);
 262         }
 263         return false;
 264     }
 265 
 266     public static Container getParent_NoClientCode(Component c) {
 267         Container parent=null;
 268 
 269         try {
 270             parent = (Container) methodGetParentNoClientCode.invoke(c, (Object[]) null);
 271         }
 272         catch (IllegalAccessException e)
 273         {
 274             log.log(Level.FINE, "Unable to access the Component object", e);
 275         }
 276         catch (InvocationTargetException e) {
 277             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 278         }
 279 
 280         return parent;
 281     }
 282 
 283     public static Font getFont_NoClientCode(Component c) {
 284         Font font=null;
 285 
 286         try {
 287             font = (Font) methodGetFontNoClientCode.invoke(c, (Object[]) null);
 288         }
 289         catch (IllegalAccessException e)
 290         {
 291             log.log(Level.FINE, "Unable to access the Component object", e);
 292         }
 293         catch (InvocationTargetException e) {
 294             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 295         }
 296 
 297         return font;
 298     }
 299 
 300     public static void processEvent(Component c, AWTEvent event) {
 301         Font font=null;
 302 
 303         try {
 304             Object[] args = new Object[1];
 305             args[0] = event;
 306             methodProcessEvent.invoke(c,args);
 307         }
 308         catch (IllegalAccessException e)
 309         {
 310             log.log(Level.FINE, "Unable to access the Component object", e);
 311         }
 312         catch (InvocationTargetException e) {
 313             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 314         }
 315     }
 316 
 317     public static void enableEvents(Component c, long event_mask) {
 318         try {
 319             Object[] args = new Object[1];
 320             args[0] = Long.valueOf(event_mask);
 321             methodEnableEvents.invoke(c,args);
 322         }
 323         catch (IllegalAccessException e)
 324         {
 325             log.log(Level.FINE, "Unable to access the Component object", e);
 326         }
 327         catch (InvocationTargetException e) {
 328             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 329         }
 330     }
 331 
 332     public static void setParent(Component c, Container parent)
 333     {
 334         try {
 335             fieldParent.set(c,parent);
 336         }
 337         catch (IllegalAccessException e)
 338         {
 339             log.log(Level.FINE, "Unable to access the Component object", e);
 340         }
 341     }
 342 
 343     public static Color getForeground(Component c)
 344     {
 345         Color color = null;
 346         try {
 347             color = (Color) fieldForeground.get(c);
 348         }
 349         catch (IllegalAccessException e)
 350         {
 351             log.log(Level.FINE, "Unable to access the Component object", e);
 352         }
 353         return color;
 354     }
 355 
 356     public static Color getBackground(Component c)
 357     {
 358         Color color = null;
 359         try {
 360             color = (Color) fieldBackground.get(c);
 361         }
 362         catch (IllegalAccessException e)
 363         {
 364             log.log(Level.FINE, "Unable to access the Component object", e);
 365         }
 366         return color;
 367     }
 368 
 369     public static void setBackground(Component c, Color color) {
 370         try {
 371             fieldBackground.set(c, color);
 372         }
 373         catch (IllegalAccessException e)
 374         {
 375             log.log(Level.FINE, "Unable to access the Component object", e);
 376         }
 377     }
 378 
 379     public static Font getFont(Component c)
 380     {
 381         Font f = null;
 382         try {
 383             f = (Font) fieldFont.get(c);
 384         }
 385         catch (IllegalAccessException e)
 386         {
 387             log.log(Level.FINE, "Unable to access the Component object", e);
 388         }
 389         return f;
 390     }
 391 
 392     public static ComponentPeer getPeer(Component c) {
 393         ComponentPeer peer = null;
 394         try {
 395             peer = (ComponentPeer)fieldPeer.get(c);
 396         }
 397         catch (IllegalAccessException e)
 398         {
 399             log.log(Level.FINE, "Unable to access the Component object", e);
 400         }
 401         return peer;
 402     }
 403 
 404     public static void setPeer(Component c, ComponentPeer peer) {
 405         try {
 406             fieldPeer.set(c, peer);
 407         } catch (IllegalAccessException e)
 408         {
 409             log.log(Level.FINE, "Unable to access the Component object", e);
 410         }
 411     }
 412 
 413     public static boolean getIgnoreRepaint(Component comp) {
 414         try {
 415             return fieldIgnoreRepaint.getBoolean(comp);
 416         }
 417         catch (IllegalAccessException e) {
 418             log.log(Level.FINE, "Unable to access the Component object", e);
 419         }
 420 
 421         return false;
 422     }
 423 
 424     public static boolean getVisible(Component c) {
 425         try {
 426             return fieldVisible.getBoolean(c);
 427         }
 428         catch (IllegalAccessException e)
 429         {
 430             log.log(Level.FINE, "Unable to access the Component object", e);
 431         }
 432         return false;
 433     }
 434 
 435     public static boolean isEnabledImpl(Component c) {
 436         boolean enabled = true;
 437         try {
 438             enabled = (Boolean) methodIsEnabledImpl.invoke(c, (Object[]) null);
 439         }
 440         catch (IllegalAccessException e)
 441         {
 442             log.log(Level.FINE, "Unable to access the Component object", e);
 443         }
 444         catch (InvocationTargetException e) {
 445             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 446         }
 447         return enabled;
 448     }
 449 
 450     public static Cursor getCursor_NoClientCode(Component c) {
 451         Cursor cursor = null;
 452 
 453         try {
 454             cursor = (Cursor) methodGetCursorNoClientCode.invoke(c, (Object[]) null);
 455         }
 456         catch (IllegalAccessException e)
 457         {
 458             log.log(Level.FINE, "Unable to access the Component object", e);
 459         }
 460         catch (InvocationTargetException e) {
 461             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 462         }
 463 
 464         return cursor;
 465     }
 466 
 467     public static Point getLocation_NoClientCode(Component c) {
 468         Point loc = null;
 469 
 470         try {
 471             loc = (Point) methodLocationNoClientCode.invoke(c, (Object[]) null);
 472         }
 473         catch (IllegalAccessException e)
 474         {
 475             log.log(Level.FINE, "Unable to access the Component object", e);
 476         }
 477         catch (InvocationTargetException e) {
 478             log.log(Level.FINE, "Unable to invoke on the Component object", e);
 479         }
 480 
 481         return loc;
 482     }
 483 }