Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]
    1   /*
    2    * Copyright 1996-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   package java.awt;
   26   
   27   import java.awt.AWTException;
   28   import java.awt.Point;
   29   import java.awt.Toolkit;
   30   
   31   import java.io.File;
   32   import java.io.FileInputStream;
   33   
   34   import java.beans.ConstructorProperties;
   35   import java.util.Hashtable;
   36   import java.util.Properties;
   37   import java.util.StringTokenizer;
   38   
   39   import java.util.logging;
   40   
   41   import java.security.AccessController;
   42   
   43   /**
   44    * A class to encapsulate the bitmap representation of the mouse cursor.
   45    *
   46    * @see Component#setCursor
   47    * @author      Amy Fowler
   48    */
   49   public class Cursor implements java.io.Serializable {
   50   
   51       /**
   52        * The default cursor type (gets set if no cursor is defined).
   53        */
   54       public static final int     DEFAULT_CURSOR                  = 0;
   55   
   56       /**
   57        * The crosshair cursor type.
   58        */
   59       public static final int     CROSSHAIR_CURSOR                = 1;
   60   
   61       /**
   62        * The text cursor type.
   63        */
   64       public static final int     TEXT_CURSOR                     = 2;
   65   
   66       /**
   67        * The wait cursor type.
   68        */
   69       public static final int     WAIT_CURSOR                     = 3;
   70   
   71       /**
   72        * The south-west-resize cursor type.
   73        */
   74       public static final int     SW_RESIZE_CURSOR                = 4;
   75   
   76       /**
   77        * The south-east-resize cursor type.
   78        */
   79       public static final int     SE_RESIZE_CURSOR                = 5;
   80   
   81       /**
   82        * The north-west-resize cursor type.
   83        */
   84       public static final int     NW_RESIZE_CURSOR                = 6;
   85   
   86       /**
   87        * The north-east-resize cursor type.
   88        */
   89       public static final int     NE_RESIZE_CURSOR                = 7;
   90   
   91       /**
   92        * The north-resize cursor type.
   93        */
   94       public static final int     N_RESIZE_CURSOR                 = 8;
   95   
   96       /**
   97        * The south-resize cursor type.
   98        */
   99       public static final int     S_RESIZE_CURSOR                 = 9;
  100   
  101       /**
  102        * The west-resize cursor type.
  103        */
  104       public static final int     W_RESIZE_CURSOR                 = 10;
  105   
  106       /**
  107        * The east-resize cursor type.
  108        */
  109       public static final int     E_RESIZE_CURSOR                 = 11;
  110   
  111       /**
  112        * The hand cursor type.
  113        */
  114       public static final int     HAND_CURSOR                     = 12;
  115   
  116       /**
  117        * The move cursor type.
  118        */
  119       public static final int     MOVE_CURSOR                     = 13;
  120   
  121       protected static Cursor predefined[] = new Cursor[14];
  122   
  123       /* Localization names and default values */
  124       static final String[][] cursorProperties = {
  125           { "AWT.DefaultCursor", "Default Cursor" },
  126           { "AWT.CrosshairCursor", "Crosshair Cursor" },
  127           { "AWT.TextCursor", "Text Cursor" },
  128           { "AWT.WaitCursor", "Wait Cursor" },
  129           { "AWT.SWResizeCursor", "Southwest Resize Cursor" },
  130           { "AWT.SEResizeCursor", "Southeast Resize Cursor" },
  131           { "AWT.NWResizeCursor", "Northwest Resize Cursor" },
  132           { "AWT.NEResizeCursor", "Northeast Resize Cursor" },
  133           { "AWT.NResizeCursor", "North Resize Cursor" },
  134           { "AWT.SResizeCursor", "South Resize Cursor" },
  135           { "AWT.WResizeCursor", "West Resize Cursor" },
  136           { "AWT.EResizeCursor", "East Resize Cursor" },
  137           { "AWT.HandCursor", "Hand Cursor" },
  138           { "AWT.MoveCursor", "Move Cursor" },
  139       };
  140   
  141       /**
  142        * The chosen cursor type initially set to
  143        * the <code>DEFAULT_CURSOR</code>.
  144        *
  145        * @serial
  146        * @see #getType()
  147        */
  148       int type = DEFAULT_CURSOR;
  149   
  150       /**
  151        * The type associated with all custom cursors.
  152        */
  153       public static final int     CUSTOM_CURSOR                   = -1;
  154   
  155       /*
  156        * hashtable, filesystem dir prefix, filename, and properties for custom cursors support
  157        */
  158   
  159       private static final Hashtable  systemCustomCursors         = new Hashtable(1);
  160       private static final String systemCustomCursorDirPrefix = initCursorDir();
  161   
  162       private static String initCursorDir() {
  163           String jhome =  (String) java.security.AccessController.doPrivileged(
  164                  new sun.security.action.GetPropertyAction("java.home"));
  165           return jhome +
  166               File.separator + "lib" + File.separator + "images" +
  167               File.separator + "cursors" + File.separator;
  168       }
  169   
  170       private static final String     systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
  171   
  172       private static       Properties systemCustomCursorProperties = null;
  173   
  174       private static final String CursorDotPrefix  = "Cursor.";
  175       private static final String DotFileSuffix    = ".File";
  176       private static final String DotHotspotSuffix = ".HotSpot";
  177       private static final String DotNameSuffix    = ".Name";
  178   
  179       /*
  180        * JDK 1.1 serialVersionUID
  181        */
  182       private static final long serialVersionUID = 8028237497568985504L;
  183   
  184       private static final Logger log = Logger.getLogger("java.awt.Cursor");
  185   
  186       static {
  187           /* ensure that the necessary native libraries are loaded */
  188           Toolkit.loadLibraries();
  189           if (!GraphicsEnvironment.isHeadless()) {
  190               initIDs();
  191           }
  192       }
  193   
  194       /**
  195        * Initialize JNI field and method IDs for fields that may be
  196        * accessed from C.
  197        */
  198       private static native void initIDs();
  199   
  200       /**
  201        * Hook into native data.
  202        */
  203       private transient long pData;
  204   
  205       private transient Object anchor = new Object();
  206   
  207       static class CursorDisposer implements sun.java2d.DisposerRecord {
  208           volatile long pData;
  209           public CursorDisposer(long pData) {
  210               this.pData = pData;
  211           }
  212           public void dispose() {
  213               if (pData != 0) {
  214                   finalizeImpl(pData);
  215               }
  216           }
  217       }
  218       transient CursorDisposer disposer;
  219       private void setPData(long pData) {
  220           this.pData = pData;
  221           if (GraphicsEnvironment.isHeadless()) {
  222               return;
  223           }
  224           if (disposer == null) {
  225               disposer = new CursorDisposer(pData);
  226               // anchor is null after deserialization
  227               if (anchor == null) {
  228                   anchor = new Object();
  229               }
  230               sun.java2d.Disposer.addRecord(anchor, disposer);
  231           } else {
  232               disposer.pData = pData;
  233           }
  234       }
  235   
  236       /**
  237        * The user-visible name of the cursor.
  238        *
  239        * @serial
  240        * @see #getName()
  241        */
  242       protected String name;
  243   
  244       /**
  245        * Returns a cursor object with the specified predefined type.
  246        *
  247        * @param type the type of predefined cursor
  248        * @return the specified predefined cursor
  249        * @throws IllegalArgumentException if the specified cursor type is
  250        *         invalid
  251        */
  252       static public Cursor getPredefinedCursor(int type) {
  253           if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
  254               throw new IllegalArgumentException("illegal cursor type");
  255           }
  256           if (predefined[type] == null) {
  257               predefined[type] = new Cursor(type);
  258           }
  259           return predefined[type];
  260       }
  261   
  262       /**
  263        * Returns a system-specific custom cursor object matching the
  264        * specified name.  Cursor names are, for example: "Invalid.16x16"
  265        *
  266        * @param name a string describing the desired system-specific custom cursor
  267        * @return the system specific custom cursor named
  268        * @exception HeadlessException if
  269        * <code>GraphicsEnvironment.isHeadless</code> returns true
  270        */
  271       static public Cursor getSystemCustomCursor(final String name)
  272           throws AWTException, HeadlessException {
  273           GraphicsEnvironment.checkHeadless();
  274           Cursor cursor = (Cursor)systemCustomCursors.get(name);
  275   
  276           if (cursor == null) {
  277               synchronized(systemCustomCursors) {
  278                   if (systemCustomCursorProperties == null)
  279                       loadSystemCustomCursorProperties();
  280               }
  281   
  282               String prefix = CursorDotPrefix + name;
  283               String key    = prefix + DotFileSuffix;
  284   
  285               if (!systemCustomCursorProperties.containsKey(key)) {
  286                   if (log.isLoggable(Level.FINER)) {
  287                       log.log(Level.FINER, "Cursor.getSystemCustomCursor(" + name + ") returned null");
  288                   }
  289                   return null;
  290               }
  291   
  292               final String fileName =
  293                   systemCustomCursorProperties.getProperty(key);
  294   
  295               String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
  296   
  297               if (localized == null) localized = name;
  298   
  299               String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
  300   
  301               if (hotspot == null)
  302                   throw new AWTException("no hotspot property defined for cursor: " + name);
  303   
  304               StringTokenizer st = new StringTokenizer(hotspot, ",");
  305   
  306               if (st.countTokens() != 2)
  307                   throw new AWTException("failed to parse hotspot property for cursor: " + name);
  308   
  309               int x = 0;
  310               int y = 0;
  311   
  312               try {
  313                   x = Integer.parseInt(st.nextToken());
  314                   y = Integer.parseInt(st.nextToken());
  315               } catch (NumberFormatException nfe) {
  316                   throw new AWTException("failed to parse hotspot property for cursor: " + name);
  317               }
  318   
  319               try {
  320                   final int fx = x;
  321                   final int fy = y;
  322                   final String flocalized = localized;
  323   
  324                   cursor = (Cursor) java.security.AccessController.doPrivileged(
  325                       new java.security.PrivilegedExceptionAction() {
  326                       public Object run() throws Exception {
  327                           Toolkit toolkit = Toolkit.getDefaultToolkit();
  328                           Image image = toolkit.getImage(
  329                              systemCustomCursorDirPrefix + fileName);
  330                           return toolkit.createCustomCursor(
  331                                       image, new Point(fx,fy), flocalized);
  332                       }
  333                   });
  334               } catch (Exception e) {
  335                   throw new AWTException(
  336                       "Exception: " + e.getClass() + " " + e.getMessage() +
  337                       " occurred while creating cursor " + name);
  338               }
  339   
  340               if (cursor == null) {
  341                   if (log.isLoggable(Level.FINER)) {
  342                       log.log(Level.FINER, "Cursor.getSystemCustomCursor(" + name + ") returned null");
  343                   }
  344               } else {
  345                   systemCustomCursors.put(name, cursor);
  346               }
  347           }
  348   
  349           return cursor;
  350       }
  351   
  352       /**
  353        * Return the system default cursor.
  354        */
  355       static public Cursor getDefaultCursor() {
  356           return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  357       }
  358   
  359       /**
  360        * Creates a new cursor object with the specified type.
  361        * @param type the type of cursor
  362        * @throws IllegalArgumentException if the specified cursor type
  363        * is invalid
  364        */
  365       @ConstructorProperties({"type"})
  366       public Cursor(int type) {
  367           if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
  368               throw new IllegalArgumentException("illegal cursor type");
  369           }
  370           this.type = type;
  371   
  372           // Lookup localized name.
  373           name = Toolkit.getProperty(cursorProperties[type][0],
  374                                      cursorProperties[type][1]);
  375       }
  376   
  377       /**
  378        * Creates a new custom cursor object with the specified name.<p>
  379        * Note:  this constructor should only be used by AWT implementations
  380        * as part of their support for custom cursors.  Applications should
  381        * use Toolkit.createCustomCursor().
  382        * @param name the user-visible name of the cursor.
  383        * @see java.awt.Toolkit#createCustomCursor
  384        */
  385       protected Cursor(String name) {
  386           this.type = Cursor.CUSTOM_CURSOR;
  387           this.name = name;
  388       }
  389   
  390       /**
  391        * Returns the type for this cursor.
  392        */
  393       public int getType() {
  394           return type;
  395       }
  396   
  397       /**
  398        * Returns the name of this cursor.
  399        * @return    a localized description of this cursor.
  400        * @since     1.2
  401        */
  402       public String getName() {
  403           return name;
  404       }
  405   
  406       /**
  407        * Returns a string representation of this cursor.
  408        * @return    a string representation of this cursor.
  409        * @since     1.2
  410        */
  411       public String toString() {
  412           return getClass().getName() + "[" + getName() + "]";
  413       }
  414   
  415       /*
  416        * load the cursor.properties file
  417        */
  418       private static void loadSystemCustomCursorProperties() throws AWTException {
  419           synchronized(systemCustomCursors) {
  420               systemCustomCursorProperties = new Properties();
  421   
  422               try {
  423                   AccessController.doPrivileged(
  424                         new java.security.PrivilegedExceptionAction() {
  425                       public Object run() throws Exception {
  426                           FileInputStream fis = null;
  427                           try {
  428                               fis = new FileInputStream(
  429                                              systemCustomCursorPropertiesFile);
  430                               systemCustomCursorProperties.load(fis);
  431                           } finally {
  432                               if (fis != null)
  433                                   fis.close();
  434                           }
  435                           return null;
  436                       }
  437                   });
  438               } catch (Exception e) {
  439                   systemCustomCursorProperties = null;
  440                    throw new AWTException("Exception: " + e.getClass() + " " +
  441                      e.getMessage() + " occurred while loading: " +
  442                                           systemCustomCursorPropertiesFile);
  443               }
  444           }
  445       }
  446   
  447       private native static void finalizeImpl(long pData);
  448   }

Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]