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