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

    1   /*
    2    * Copyright (c) 1996, 2007, Oracle and/or its affiliates. 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.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * 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.security.AccessController;
   40   
   41   import sun.util.logging.PlatformLogger;
   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       /**
  122         * @deprecated As of JDK version 1.7, the {@link #getPredefinedCursor(int)}
  123         * method should be used instead.
  124         */
  125       @Deprecated
  126       protected static Cursor predefined[] = new Cursor[14];
  127   
  128       /**
  129        * This field is a private replacement for 'predefined' array.
  130        */
  131       private final static Cursor[] predefinedPrivate = new Cursor[14];
  132   
  133       /* Localization names and default values */
  134       static final String[][] cursorProperties = {
  135           { "AWT.DefaultCursor", "Default Cursor" },
  136           { "AWT.CrosshairCursor", "Crosshair Cursor" },
  137           { "AWT.TextCursor", "Text Cursor" },
  138           { "AWT.WaitCursor", "Wait Cursor" },
  139           { "AWT.SWResizeCursor", "Southwest Resize Cursor" },
  140           { "AWT.SEResizeCursor", "Southeast Resize Cursor" },
  141           { "AWT.NWResizeCursor", "Northwest Resize Cursor" },
  142           { "AWT.NEResizeCursor", "Northeast Resize Cursor" },
  143           { "AWT.NResizeCursor", "North Resize Cursor" },
  144           { "AWT.SResizeCursor", "South Resize Cursor" },
  145           { "AWT.WResizeCursor", "West Resize Cursor" },
  146           { "AWT.EResizeCursor", "East Resize Cursor" },
  147           { "AWT.HandCursor", "Hand Cursor" },
  148           { "AWT.MoveCursor", "Move Cursor" },
  149       };
  150   
  151       /**
  152        * The chosen cursor type initially set to
  153        * the <code>DEFAULT_CURSOR</code>.
  154        *
  155        * @serial
  156        * @see #getType()
  157        */
  158       int type = DEFAULT_CURSOR;
  159   
  160       /**
  161        * The type associated with all custom cursors.
  162        */
  163       public static final int     CUSTOM_CURSOR                   = -1;
  164   
  165       /*
  166        * hashtable, filesystem dir prefix, filename, and properties for custom cursors support
  167        */
  168   
  169       private static final Hashtable  systemCustomCursors         = new Hashtable(1);
  170       private static final String systemCustomCursorDirPrefix = initCursorDir();
  171   
  172       private static String initCursorDir() {
  173           String jhome =  (String) java.security.AccessController.doPrivileged(
  174                  new sun.security.action.GetPropertyAction("java.home"));
  175           return jhome +
  176               File.separator + "lib" + File.separator + "images" +
  177               File.separator + "cursors" + File.separator;
  178       }
  179   
  180       private static final String     systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
  181   
  182       private static       Properties systemCustomCursorProperties = null;
  183   
  184       private static final String CursorDotPrefix  = "Cursor.";
  185       private static final String DotFileSuffix    = ".File";
  186       private static final String DotHotspotSuffix = ".HotSpot";
  187       private static final String DotNameSuffix    = ".Name";
  188   
  189       /*
  190        * JDK 1.1 serialVersionUID
  191        */
  192       private static final long serialVersionUID = 8028237497568985504L;
  193   
  194       private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Cursor");
  195   
  196       static {
  197           /* ensure that the necessary native libraries are loaded */
  198           Toolkit.loadLibraries();
  199           if (!GraphicsEnvironment.isHeadless()) {
  200               initIDs();
  201           }
  202       }
  203   
  204       /**
  205        * Initialize JNI field and method IDs for fields that may be
  206        * accessed from C.
  207        */
  208       private static native void initIDs();
  209   
  210       /**
  211        * Hook into native data.
  212        */
  213       private transient long pData;
  214   
  215       private transient Object anchor = new Object();
  216   
  217       static class CursorDisposer implements sun.java2d.DisposerRecord {
  218           volatile long pData;
  219           public CursorDisposer(long pData) {
  220               this.pData = pData;
  221           }
  222           public void dispose() {
  223               if (pData != 0) {
  224                   finalizeImpl(pData);
  225               }
  226           }
  227       }
  228       transient CursorDisposer disposer;
  229       private void setPData(long pData) {
  230           this.pData = pData;
  231           if (GraphicsEnvironment.isHeadless()) {
  232               return;
  233           }
  234           if (disposer == null) {
  235               disposer = new CursorDisposer(pData);
  236               // anchor is null after deserialization
  237               if (anchor == null) {
  238                   anchor = new Object();
  239               }
  240               sun.java2d.Disposer.addRecord(anchor, disposer);
  241           } else {
  242               disposer.pData = pData;
  243           }
  244       }
  245   
  246       /**
  247        * The user-visible name of the cursor.
  248        *
  249        * @serial
  250        * @see #getName()
  251        */
  252       protected String name;
  253   
  254       /**
  255        * Returns a cursor object with the specified predefined type.
  256        *
  257        * @param type the type of predefined cursor
  258        * @return the specified predefined cursor
  259        * @throws IllegalArgumentException if the specified cursor type is
  260        *         invalid
  261        */
  262       static public Cursor getPredefinedCursor(int type) {
  263           if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
  264               throw new IllegalArgumentException("illegal cursor type");
  265           }
  266           Cursor c = predefinedPrivate[type];
  267           if (c == null) {
  268               predefinedPrivate[type] = c = new Cursor(type);
  269           }
  270           // fill 'predefined' array for backwards compatibility.
  271           if (predefined[type] == null) {
  272               predefined[type] = c;
  273           }
  274           return c;
  275       }
  276   
  277       /**
  278        * Returns a system-specific custom cursor object matching the
  279        * specified name.  Cursor names are, for example: "Invalid.16x16"
  280        *
  281        * @param name a string describing the desired system-specific custom cursor
  282        * @return the system specific custom cursor named
  283        * @exception HeadlessException if
  284        * <code>GraphicsEnvironment.isHeadless</code> returns true
  285        */
  286       static public Cursor getSystemCustomCursor(final String name)
  287           throws AWTException, HeadlessException {
  288           GraphicsEnvironment.checkHeadless();
  289           Cursor cursor = (Cursor)systemCustomCursors.get(name);
  290   
  291           if (cursor == null) {
  292               synchronized(systemCustomCursors) {
  293                   if (systemCustomCursorProperties == null)
  294                       loadSystemCustomCursorProperties();
  295               }
  296   
  297               String prefix = CursorDotPrefix + name;
  298               String key    = prefix + DotFileSuffix;
  299   
  300               if (!systemCustomCursorProperties.containsKey(key)) {
  301                   if (log.isLoggable(PlatformLogger.FINER)) {
  302                       log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
  303                   }
  304                   return null;
  305               }
  306   
  307               final String fileName =
  308                   systemCustomCursorProperties.getProperty(key);
  309   
  310               String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
  311   
  312               if (localized == null) localized = name;
  313   
  314               String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
  315   
  316               if (hotspot == null)
  317                   throw new AWTException("no hotspot property defined for cursor: " + name);
  318   
  319               StringTokenizer st = new StringTokenizer(hotspot, ",");
  320   
  321               if (st.countTokens() != 2)
  322                   throw new AWTException("failed to parse hotspot property for cursor: " + name);
  323   
  324               int x = 0;
  325               int y = 0;
  326   
  327               try {
  328                   x = Integer.parseInt(st.nextToken());
  329                   y = Integer.parseInt(st.nextToken());
  330               } catch (NumberFormatException nfe) {
  331                   throw new AWTException("failed to parse hotspot property for cursor: " + name);
  332               }
  333   
  334               try {
  335                   final int fx = x;
  336                   final int fy = y;
  337                   final String flocalized = localized;
  338   
  339                   cursor = (Cursor) java.security.AccessController.doPrivileged(
  340                       new java.security.PrivilegedExceptionAction() {
  341                       public Object run() throws Exception {
  342                           Toolkit toolkit = Toolkit.getDefaultToolkit();
  343                           Image image = toolkit.getImage(
  344                              systemCustomCursorDirPrefix + fileName);
  345                           return toolkit.createCustomCursor(
  346                                       image, new Point(fx,fy), flocalized);
  347                       }
  348                   });
  349               } catch (Exception e) {
  350                   throw new AWTException(
  351                       "Exception: " + e.getClass() + " " + e.getMessage() +
  352                       " occurred while creating cursor " + name);
  353               }
  354   
  355               if (cursor == null) {
  356                   if (log.isLoggable(PlatformLogger.FINER)) {
  357                       log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
  358                   }
  359               } else {
  360                   systemCustomCursors.put(name, cursor);
  361               }
  362           }
  363   
  364           return cursor;
  365       }
  366   
  367       /**
  368        * Return the system default cursor.
  369        */
  370       static public Cursor getDefaultCursor() {
  371           return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  372       }
  373   
  374       /**
  375        * Creates a new cursor object with the specified type.
  376        * @param type the type of cursor
  377        * @throws IllegalArgumentException if the specified cursor type
  378        * is invalid
  379        */
  380       @ConstructorProperties({"type"})
  381       public Cursor(int type) {
  382           if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
  383               throw new IllegalArgumentException("illegal cursor type");
  384           }
  385           this.type = type;
  386   
  387           // Lookup localized name.
  388           name = Toolkit.getProperty(cursorProperties[type][0],
  389                                      cursorProperties[type][1]);
  390       }
  391   
  392       /**
  393        * Creates a new custom cursor object with the specified name.<p>
  394        * Note:  this constructor should only be used by AWT implementations
  395        * as part of their support for custom cursors.  Applications should
  396        * use Toolkit.createCustomCursor().
  397        * @param name the user-visible name of the cursor.
  398        * @see java.awt.Toolkit#createCustomCursor
  399        */
  400       protected Cursor(String name) {
  401           this.type = Cursor.CUSTOM_CURSOR;
  402           this.name = name;
  403       }
  404   
  405       /**
  406        * Returns the type for this cursor.
  407        */
  408       public int getType() {
  409           return type;
  410       }
  411   
  412       /**
  413        * Returns the name of this cursor.
  414        * @return    a localized description of this cursor.
  415        * @since     1.2
  416        */
  417       public String getName() {
  418           return name;
  419       }
  420   
  421       /**
  422        * Returns a string representation of this cursor.
  423        * @return    a string representation of this cursor.
  424        * @since     1.2
  425        */
  426       public String toString() {
  427           return getClass().getName() + "[" + getName() + "]";
  428       }
  429   
  430       /*
  431        * load the cursor.properties file
  432        */
  433       private static void loadSystemCustomCursorProperties() throws AWTException {
  434           synchronized(systemCustomCursors) {
  435               systemCustomCursorProperties = new Properties();
  436   
  437               try {
  438                   AccessController.doPrivileged(
  439                         new java.security.PrivilegedExceptionAction() {
  440                       public Object run() throws Exception {
  441                           FileInputStream fis = null;
  442                           try {
  443                               fis = new FileInputStream(
  444                                              systemCustomCursorPropertiesFile);
  445                               systemCustomCursorProperties.load(fis);
  446                           } finally {
  447                               if (fis != null)
  448                                   fis.close();
  449                           }
  450                           return null;
  451                       }
  452                   });
  453               } catch (Exception e) {
  454                   systemCustomCursorProperties = null;
  455                    throw new AWTException("Exception: " + e.getClass() + " " +
  456                      e.getMessage() + " occurred while loading: " +
  457                                           systemCustomCursorPropertiesFile);
  458               }
  459           }
  460       }
  461   
  462       private native static void finalizeImpl(long pData);
  463   }

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