--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/awt/Cursor.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,448 @@
+/*
+ * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package java.awt;
+
+import java.awt.AWTException;
+import java.awt.Point;
+import java.awt.Toolkit;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.beans.ConstructorProperties;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import java.util.logging.*;
+
+import java.security.AccessController;
+
+/**
+ * A class to encapsulate the bitmap representation of the mouse cursor.
+ *
+ * @see Component#setCursor
+ * @author Amy Fowler
+ */
+public class Cursor implements java.io.Serializable {
+
+ /**
+ * The default cursor type (gets set if no cursor is defined).
+ */
+ public static final int DEFAULT_CURSOR = 0;
+
+ /**
+ * The crosshair cursor type.
+ */
+ public static final int CROSSHAIR_CURSOR = 1;
+
+ /**
+ * The text cursor type.
+ */
+ public static final int TEXT_CURSOR = 2;
+
+ /**
+ * The wait cursor type.
+ */
+ public static final int WAIT_CURSOR = 3;
+
+ /**
+ * The south-west-resize cursor type.
+ */
+ public static final int SW_RESIZE_CURSOR = 4;
+
+ /**
+ * The south-east-resize cursor type.
+ */
+ public static final int SE_RESIZE_CURSOR = 5;
+
+ /**
+ * The north-west-resize cursor type.
+ */
+ public static final int NW_RESIZE_CURSOR = 6;
+
+ /**
+ * The north-east-resize cursor type.
+ */
+ public static final int NE_RESIZE_CURSOR = 7;
+
+ /**
+ * The north-resize cursor type.
+ */
+ public static final int N_RESIZE_CURSOR = 8;
+
+ /**
+ * The south-resize cursor type.
+ */
+ public static final int S_RESIZE_CURSOR = 9;
+
+ /**
+ * The west-resize cursor type.
+ */
+ public static final int W_RESIZE_CURSOR = 10;
+
+ /**
+ * The east-resize cursor type.
+ */
+ public static final int E_RESIZE_CURSOR = 11;
+
+ /**
+ * The hand cursor type.
+ */
+ public static final int HAND_CURSOR = 12;
+
+ /**
+ * The move cursor type.
+ */
+ public static final int MOVE_CURSOR = 13;
+
+ protected static Cursor predefined[] = new Cursor[14];
+
+ /* Localization names and default values */
+ static final String[][] cursorProperties = {
+ { "AWT.DefaultCursor", "Default Cursor" },
+ { "AWT.CrosshairCursor", "Crosshair Cursor" },
+ { "AWT.TextCursor", "Text Cursor" },
+ { "AWT.WaitCursor", "Wait Cursor" },
+ { "AWT.SWResizeCursor", "Southwest Resize Cursor" },
+ { "AWT.SEResizeCursor", "Southeast Resize Cursor" },
+ { "AWT.NWResizeCursor", "Northwest Resize Cursor" },
+ { "AWT.NEResizeCursor", "Northeast Resize Cursor" },
+ { "AWT.NResizeCursor", "North Resize Cursor" },
+ { "AWT.SResizeCursor", "South Resize Cursor" },
+ { "AWT.WResizeCursor", "West Resize Cursor" },
+ { "AWT.EResizeCursor", "East Resize Cursor" },
+ { "AWT.HandCursor", "Hand Cursor" },
+ { "AWT.MoveCursor", "Move Cursor" },
+ };
+
+ /**
+ * The chosen cursor type initially set to
+ * the <code>DEFAULT_CURSOR</code>.
+ *
+ * @serial
+ * @see #getType()
+ */
+ int type = DEFAULT_CURSOR;
+
+ /**
+ * The type associated with all custom cursors.
+ */
+ public static final int CUSTOM_CURSOR = -1;
+
+ /*
+ * hashtable, filesystem dir prefix, filename, and properties for custom cursors support
+ */
+
+ private static final Hashtable systemCustomCursors = new Hashtable(1);
+ private static final String systemCustomCursorDirPrefix = initCursorDir();
+
+ private static String initCursorDir() {
+ String jhome = (String) java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("java.home"));
+ return jhome +
+ File.separator + "lib" + File.separator + "images" +
+ File.separator + "cursors" + File.separator;
+ }
+
+ private static final String systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
+
+ private static Properties systemCustomCursorProperties = null;
+
+ private static final String CursorDotPrefix = "Cursor.";
+ private static final String DotFileSuffix = ".File";
+ private static final String DotHotspotSuffix = ".HotSpot";
+ private static final String DotNameSuffix = ".Name";
+
+ /*
+ * JDK 1.1 serialVersionUID
+ */
+ private static final long serialVersionUID = 8028237497568985504L;
+
+ private static final Logger log = Logger.getLogger("java.awt.Cursor");
+
+ static {
+ /* ensure that the necessary native libraries are loaded */
+ Toolkit.loadLibraries();
+ if (!GraphicsEnvironment.isHeadless()) {
+ initIDs();
+ }
+ }
+
+ /**
+ * Initialize JNI field and method IDs for fields that may be
+ * accessed from C.
+ */
+ private static native void initIDs();
+
+ /**
+ * Hook into native data.
+ */
+ private transient long pData;
+
+ private transient Object anchor = new Object();
+
+ static class CursorDisposer implements sun.java2d.DisposerRecord {
+ volatile long pData;
+ public CursorDisposer(long pData) {
+ this.pData = pData;
+ }
+ public void dispose() {
+ if (pData != 0) {
+ finalizeImpl(pData);
+ }
+ }
+ }
+ transient CursorDisposer disposer;
+ private void setPData(long pData) {
+ this.pData = pData;
+ if (GraphicsEnvironment.isHeadless()) {
+ return;
+ }
+ if (disposer == null) {
+ disposer = new CursorDisposer(pData);
+ // anchor is null after deserialization
+ if (anchor == null) {
+ anchor = new Object();
+ }
+ sun.java2d.Disposer.addRecord(anchor, disposer);
+ } else {
+ disposer.pData = pData;
+ }
+ }
+
+ /**
+ * The user-visible name of the cursor.
+ *
+ * @serial
+ * @see #getName()
+ */
+ protected String name;
+
+ /**
+ * Returns a cursor object with the specified predefined type.
+ *
+ * @param type the type of predefined cursor
+ * @return the specified predefined cursor
+ * @throws IllegalArgumentException if the specified cursor type is
+ * invalid
+ */
+ static public Cursor getPredefinedCursor(int type) {
+ if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
+ throw new IllegalArgumentException("illegal cursor type");
+ }
+ if (predefined[type] == null) {
+ predefined[type] = new Cursor(type);
+ }
+ return predefined[type];
+ }
+
+ /**
+ * Returns a system-specific custom cursor object matching the
+ * specified name. Cursor names are, for example: "Invalid.16x16"
+ *
+ * @param name a string describing the desired system-specific custom cursor
+ * @return the system specific custom cursor named
+ * @exception HeadlessException if
+ * <code>GraphicsEnvironment.isHeadless</code> returns true
+ */
+ static public Cursor getSystemCustomCursor(final String name)
+ throws AWTException, HeadlessException {
+ GraphicsEnvironment.checkHeadless();
+ Cursor cursor = (Cursor)systemCustomCursors.get(name);
+
+ if (cursor == null) {
+ synchronized(systemCustomCursors) {
+ if (systemCustomCursorProperties == null)
+ loadSystemCustomCursorProperties();
+ }
+
+ String prefix = CursorDotPrefix + name;
+ String key = prefix + DotFileSuffix;
+
+ if (!systemCustomCursorProperties.containsKey(key)) {
+ if (log.isLoggable(Level.FINER)) {
+ log.log(Level.FINER, "Cursor.getSystemCustomCursor(" + name + ") returned null");
+ }
+ return null;
+ }
+
+ final String fileName =
+ systemCustomCursorProperties.getProperty(key);
+
+ String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
+
+ if (localized == null) localized = name;
+
+ String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
+
+ if (hotspot == null)
+ throw new AWTException("no hotspot property defined for cursor: " + name);
+
+ StringTokenizer st = new StringTokenizer(hotspot, ",");
+
+ if (st.countTokens() != 2)
+ throw new AWTException("failed to parse hotspot property for cursor: " + name);
+
+ int x = 0;
+ int y = 0;
+
+ try {
+ x = Integer.parseInt(st.nextToken());
+ y = Integer.parseInt(st.nextToken());
+ } catch (NumberFormatException nfe) {
+ throw new AWTException("failed to parse hotspot property for cursor: " + name);
+ }
+
+ try {
+ final int fx = x;
+ final int fy = y;
+ final String flocalized = localized;
+
+ cursor = (Cursor) java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ Image image = toolkit.getImage(
+ systemCustomCursorDirPrefix + fileName);
+ return toolkit.createCustomCursor(
+ image, new Point(fx,fy), flocalized);
+ }
+ });
+ } catch (Exception e) {
+ throw new AWTException(
+ "Exception: " + e.getClass() + " " + e.getMessage() +
+ " occurred while creating cursor " + name);
+ }
+
+ if (cursor == null) {
+ if (log.isLoggable(Level.FINER)) {
+ log.log(Level.FINER, "Cursor.getSystemCustomCursor(" + name + ") returned null");
+ }
+ } else {
+ systemCustomCursors.put(name, cursor);
+ }
+ }
+
+ return cursor;
+ }
+
+ /**
+ * Return the system default cursor.
+ */
+ static public Cursor getDefaultCursor() {
+ return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+ }
+
+ /**
+ * Creates a new cursor object with the specified type.
+ * @param type the type of cursor
+ * @throws IllegalArgumentException if the specified cursor type
+ * is invalid
+ */
+ @ConstructorProperties({"type"})
+ public Cursor(int type) {
+ if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
+ throw new IllegalArgumentException("illegal cursor type");
+ }
+ this.type = type;
+
+ // Lookup localized name.
+ name = Toolkit.getProperty(cursorProperties[type][0],
+ cursorProperties[type][1]);
+ }
+
+ /**
+ * Creates a new custom cursor object with the specified name.<p>
+ * Note: this constructor should only be used by AWT implementations
+ * as part of their support for custom cursors. Applications should
+ * use Toolkit.createCustomCursor().
+ * @param name the user-visible name of the cursor.
+ * @see java.awt.Toolkit#createCustomCursor
+ */
+ protected Cursor(String name) {
+ this.type = Cursor.CUSTOM_CURSOR;
+ this.name = name;
+ }
+
+ /**
+ * Returns the type for this cursor.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Returns the name of this cursor.
+ * @return a localized description of this cursor.
+ * @since 1.2
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns a string representation of this cursor.
+ * @return a string representation of this cursor.
+ * @since 1.2
+ */
+ public String toString() {
+ return getClass().getName() + "[" + getName() + "]";
+ }
+
+ /*
+ * load the cursor.properties file
+ */
+ private static void loadSystemCustomCursorProperties() throws AWTException {
+ synchronized(systemCustomCursors) {
+ systemCustomCursorProperties = new Properties();
+
+ try {
+ AccessController.doPrivileged(
+ new java.security.PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(
+ systemCustomCursorPropertiesFile);
+ systemCustomCursorProperties.load(fis);
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ systemCustomCursorProperties = null;
+ throw new AWTException("Exception: " + e.getClass() + " " +
+ e.getMessage() + " occurred while loading: " +
+ systemCustomCursorPropertiesFile);
+ }
+ }
+ }
+
+ private native static void finalizeImpl(long pData);
+}