001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Dmitry A. Durnev
019: * @version $Revision$
020: */package java.awt;
021:
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.FileNotFoundException;
025: import java.io.IOException;
026:
027: import java.io.Serializable;
028: import java.util.HashMap;
029: import java.util.Map;
030: import java.util.Properties;
031:
032: import org.apache.harmony.awt.internal.nls.Messages;
033: import org.apache.harmony.awt.wtk.NativeCursor;
034:
035: public class Cursor implements Serializable {
036: private static final long serialVersionUID = 8028237497568985504L;
037: public static final int DEFAULT_CURSOR = 0;
038:
039: public static final int CROSSHAIR_CURSOR = 1;
040:
041: public static final int TEXT_CURSOR = 2;
042:
043: public static final int WAIT_CURSOR = 3;
044:
045: public static final int SW_RESIZE_CURSOR = 4;
046:
047: public static final int SE_RESIZE_CURSOR = 5;
048:
049: public static final int NW_RESIZE_CURSOR = 6;
050:
051: public static final int NE_RESIZE_CURSOR = 7;
052:
053: public static final int N_RESIZE_CURSOR = 8;
054:
055: public static final int S_RESIZE_CURSOR = 9;
056:
057: public static final int W_RESIZE_CURSOR = 10;
058:
059: public static final int E_RESIZE_CURSOR = 11;
060:
061: public static final int HAND_CURSOR = 12;
062:
063: public static final int MOVE_CURSOR = 13;
064:
065: /**
066: * A mapping from names to system custom cursors
067: */
068: static Map<String, Cursor> systemCustomCursors;
069: static Properties cursorProps;
070:
071: static final String[] predefinedNames = {
072: "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
073: "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
074: "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
075: "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
076: "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
077:
078: };
079:
080: protected static Cursor[] predefined = {
081: new Cursor(DEFAULT_CURSOR), null, null, null, null, null,
082: null, null, null, null, null, null, null, null };
083:
084: public static final int CUSTOM_CURSOR = -1;
085:
086: protected String name;
087:
088: private final int type;
089: private transient NativeCursor nativeCursor;
090: private Point hotSpot;
091: private Image image;
092:
093: protected Cursor(String name) {
094: this (name, null, new Point());
095: }
096:
097: public Cursor(int type) {
098: checkType(type);
099: this .type = type;
100: if ((type >= 0) && (type < predefinedNames.length)) {
101: name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
102: }
103: }
104:
105: Cursor(String name, Image img, Point hotSpot) {
106: this .name = name;
107: type = CUSTOM_CURSOR;
108: this .hotSpot = hotSpot;
109: image = img;
110: }
111:
112: @Override
113: protected void finalize() throws Throwable {
114: if (nativeCursor != null) {
115: nativeCursor.destroyCursor();
116: }
117: }
118:
119: public String getName() {
120: return name;
121: }
122:
123: @Override
124: public String toString() {
125: return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
126: }
127:
128: public int getType() {
129: return type;
130: }
131:
132: public static Cursor getPredefinedCursor(int type) {
133: checkType(type);
134: Cursor cursor = predefined[type];
135: if (cursor == null) {
136: cursor = new Cursor(type);
137: predefined[type] = cursor;
138: }
139: return cursor;
140: }
141:
142: public static Cursor getDefaultCursor() {
143: return getPredefinedCursor(DEFAULT_CURSOR);
144: }
145:
146: public static Cursor getSystemCustomCursor(String name)
147: throws AWTException, HeadlessException {
148: Toolkit.checkHeadless();
149: return getSystemCustomCursorFromMap(name);
150: }
151:
152: private static Cursor getSystemCustomCursorFromMap(String name)
153: throws AWTException {
154: loadCursorProps();
155: if (systemCustomCursors == null) {
156: systemCustomCursors = new HashMap<String, Cursor>();
157: }
158: Cursor cursor = systemCustomCursors.get(name);
159: if (cursor != null) {
160: return cursor;
161: }
162: // awt.141=failed to parse hotspot property for cursor:
163: String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
164: String nm = "Cursor." + name; //$NON-NLS-1$
165: String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
166: String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
167: String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
168: int idx = hotSpotStr.indexOf(',');
169: if (idx < 0) {
170: throw new AWTException(exMsg);
171: }
172: int x, y;
173: try {
174: x = new Integer(hotSpotStr.substring(0, idx)).intValue();
175: y = new Integer(hotSpotStr.substring(idx + 1, hotSpotStr
176: .length())).intValue();
177: } catch (NumberFormatException nfe) {
178: throw new AWTException(exMsg);
179: }
180: Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
181: cursor = new Cursor(nameStr, img, new Point(x, y));
182: systemCustomCursors.put(name, cursor);
183:
184: return cursor;
185: }
186:
187: private static void loadCursorProps() throws AWTException {
188: if (cursorProps != null) {
189: return;
190: }
191: String sep = File.separator;
192: String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
193: String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
194: cursorsDir;
195: String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
196: String cursorPropsFullFileName = (cursorsAbsDir + sep + cursorPropsFileName);
197: cursorProps = new Properties();
198: try {
199: cursorProps.load(new FileInputStream(new File(
200: cursorPropsFullFileName)));
201: } catch (FileNotFoundException e) {
202: // awt.142=Exception: class {0} {1} occurred while loading: {2}
203: throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
204: new Object[] { e.getClass(), e.getMessage(),
205: cursorPropsFullFileName }));
206: } catch (IOException e) {
207: throw new AWTException(e.getMessage());
208: }
209:
210: }
211:
212: static void checkType(int type) {
213: // can't use predefined array here because it may not have been
214: // initialized yet
215: if ((type < 0) || (type >= predefinedNames.length)) {
216: // awt.143=illegal cursor type
217: throw new IllegalArgumentException(Messages
218: .getString("awt.143")); //$NON-NLS-1$
219: }
220: }
221:
222: // "lazily" create native cursors:
223: NativeCursor getNativeCursor() {
224: if (nativeCursor != null) {
225: return nativeCursor;
226: }
227: Toolkit toolkit = Toolkit.getDefaultToolkit();
228: if (type != CUSTOM_CURSOR) {
229: nativeCursor = toolkit.createNativeCursor(type);
230: } else {
231: nativeCursor = toolkit.createCustomNativeCursor(image,
232: hotSpot, name);
233: }
234: return nativeCursor;
235: }
236:
237: void setNativeCursor(NativeCursor nativeCursor) {
238: this.nativeCursor = nativeCursor;
239: }
240: }
|