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.beans.ConstructorProperties;
28 import java.io.InputStream;
29 import java.net.URL;
30 import java.security.AccessController;
31 import java.security.PrivilegedExceptionAction;
32 import java.util.Hashtable;
33 import java.util.Properties;
34 import java.util.StringTokenizer;
35
36 import sun.awt.AWTAccessor;
37 import sun.util.logging.PlatformLogger;
38
39 /**
40 * A class to encapsulate the bitmap representation of the mouse cursor.
41 *
42 * @see Component#setCursor
43 * @author Amy Fowler
44 */
45 public class Cursor implements java.io.Serializable {
46
47 /**
48 * The default cursor type (gets set if no cursor is defined).
49 */
50 public static final int DEFAULT_CURSOR = 0;
244 disposer.pData = pData;
245 }
246 }
247
248 /**
249 * The user-visible name of the cursor.
250 *
251 * @serial
252 * @see #getName()
253 */
254 protected String name;
255
256 /**
257 * Returns a cursor object with the specified predefined type.
258 *
259 * @param type the type of predefined cursor
260 * @return the specified predefined cursor
261 * @throws IllegalArgumentException if the specified cursor type is
262 * invalid
263 */
264 static public Cursor getPredefinedCursor(int type) {
265 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
266 throw new IllegalArgumentException("illegal cursor type");
267 }
268 Cursor c = predefinedPrivate[type];
269 if (c == null) {
270 predefinedPrivate[type] = c = new Cursor(type);
271 }
272 // fill 'predefined' array for backwards compatibility.
273 if (predefined[type] == null) {
274 predefined[type] = c;
275 }
276 return c;
277 }
278
279 /**
280 * Returns a system-specific custom cursor object matching the
281 * specified name. Cursor names are, for example: "Invalid.16x16"
282 *
283 * @param name a string describing the desired system-specific custom cursor
284 * @return the system specific custom cursor named
285 * @exception HeadlessException if
286 * <code>GraphicsEnvironment.isHeadless</code> returns true
287 * @exception AWTException in case of erroneous retrieving of the cursor
288 */
289 static public Cursor getSystemCustomCursor(final String name)
290 throws AWTException, HeadlessException {
291 GraphicsEnvironment.checkHeadless();
292 Cursor cursor = systemCustomCursors.get(name);
293
294 if (cursor == null) {
295 synchronized(systemCustomCursors) {
296 if (systemCustomCursorProperties == null)
297 loadSystemCustomCursorProperties();
298 }
299
300 String prefix = CURSOR_DOT_PREFIX + name;
301 String key = prefix + DOT_FILE_SUFFIX;
302
303 if (!systemCustomCursorProperties.containsKey(key)) {
304 if (log.isLoggable(PlatformLogger.Level.FINER)) {
305 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
306 }
307 return null;
308 }
309
313 final String localized = systemCustomCursorProperties.getProperty(
314 prefix + DOT_NAME_SUFFIX, name);
315
316 String hotspot = systemCustomCursorProperties.getProperty(prefix + DOT_HOTSPOT_SUFFIX);
317
318 if (hotspot == null)
319 throw new AWTException("no hotspot property defined for cursor: " + name);
320
321 StringTokenizer st = new StringTokenizer(hotspot, ",");
322
323 if (st.countTokens() != 2)
324 throw new AWTException("failed to parse hotspot property for cursor: " + name);
325
326 final Point hotPoint;
327 try {
328 hotPoint = new Point(Integer.parseInt(st.nextToken()),
329 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 Toolkit toolkit = Toolkit.getDefaultToolkit();
336 final String file = RESOURCE_PREFIX + fileName;
337
338 cursor = AccessController.doPrivileged(
339 (PrivilegedExceptionAction<Cursor>) () -> {
340 URL url = Cursor.class.getResource(file);
341 Image image = toolkit.getImage(url);
342 return toolkit.createCustomCursor(image, hotPoint,
343 localized);
344 });
345 } catch (Exception e) {
346 throw new AWTException(
347 "Exception: " + e.getClass() + " " + e.getMessage() +
348 " occurred while creating cursor " + name);
349 }
350
351 if (cursor == null) {
352 if (log.isLoggable(PlatformLogger.Level.FINER)) {
353 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
354 }
355 } else {
356 systemCustomCursors.put(name, cursor);
357 }
358 }
359
360 return cursor;
361 }
362
363 /**
364 * Return the system default cursor.
365 *
366 * @return the default cursor
367 */
368 static public Cursor getDefaultCursor() {
369 return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
370 }
371
372 /**
373 * Creates a new cursor object with the specified type.
374 * @param type the type of cursor
375 * @throws IllegalArgumentException if the specified cursor type
376 * is invalid
377 */
378 @ConstructorProperties({"type"})
379 public Cursor(int type) {
380 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
381 throw new IllegalArgumentException("illegal cursor type");
382 }
383 this.type = type;
384
385 // Lookup localized name.
386 name = Toolkit.getProperty(cursorProperties[type][0],
387 cursorProperties[type][1]);
388 }
|
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.beans.ConstructorProperties;
28 import java.io.ByteArrayOutputStream;
29 import java.io.InputStream;
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32 import java.security.PrivilegedExceptionAction;
33 import java.util.Hashtable;
34 import java.util.Properties;
35 import java.util.StringTokenizer;
36
37 import sun.awt.AWTAccessor;
38 import sun.util.logging.PlatformLogger;
39
40 /**
41 * A class to encapsulate the bitmap representation of the mouse cursor.
42 *
43 * @see Component#setCursor
44 * @author Amy Fowler
45 */
46 public class Cursor implements java.io.Serializable {
47
48 /**
49 * The default cursor type (gets set if no cursor is defined).
50 */
51 public static final int DEFAULT_CURSOR = 0;
245 disposer.pData = pData;
246 }
247 }
248
249 /**
250 * The user-visible name of the cursor.
251 *
252 * @serial
253 * @see #getName()
254 */
255 protected String name;
256
257 /**
258 * Returns a cursor object with the specified predefined type.
259 *
260 * @param type the type of predefined cursor
261 * @return the specified predefined cursor
262 * @throws IllegalArgumentException if the specified cursor type is
263 * invalid
264 */
265 public static Cursor getPredefinedCursor(int type) {
266 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
267 throw new IllegalArgumentException("illegal cursor type");
268 }
269 Cursor c = predefinedPrivate[type];
270 if (c == null) {
271 predefinedPrivate[type] = c = new Cursor(type);
272 }
273 // fill 'predefined' array for backwards compatibility.
274 if (predefined[type] == null) {
275 predefined[type] = c;
276 }
277 return c;
278 }
279
280 /**
281 * Returns a system-specific custom cursor object matching the
282 * specified name. Cursor names are, for example: "Invalid.16x16"
283 *
284 * @param name a string describing the desired system-specific custom cursor
285 * @return the system specific custom cursor named
286 * @exception HeadlessException if
287 * <code>GraphicsEnvironment.isHeadless</code> returns true
288 * @exception AWTException in case of erroneous retrieving of the cursor
289 */
290 public static Cursor getSystemCustomCursor(final String name)
291 throws AWTException, HeadlessException {
292 GraphicsEnvironment.checkHeadless();
293 Cursor cursor = systemCustomCursors.get(name);
294
295 if (cursor == null) {
296 synchronized(systemCustomCursors) {
297 if (systemCustomCursorProperties == null)
298 loadSystemCustomCursorProperties();
299 }
300
301 String prefix = CURSOR_DOT_PREFIX + name;
302 String key = prefix + DOT_FILE_SUFFIX;
303
304 if (!systemCustomCursorProperties.containsKey(key)) {
305 if (log.isLoggable(PlatformLogger.Level.FINER)) {
306 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
307 }
308 return null;
309 }
310
314 final String localized = systemCustomCursorProperties.getProperty(
315 prefix + DOT_NAME_SUFFIX, name);
316
317 String hotspot = systemCustomCursorProperties.getProperty(prefix + DOT_HOTSPOT_SUFFIX);
318
319 if (hotspot == null)
320 throw new AWTException("no hotspot property defined for cursor: " + name);
321
322 StringTokenizer st = new StringTokenizer(hotspot, ",");
323
324 if (st.countTokens() != 2)
325 throw new AWTException("failed to parse hotspot property for cursor: " + name);
326
327 final Point hotPoint;
328 try {
329 hotPoint = new Point(Integer.parseInt(st.nextToken()),
330 Integer.parseInt(st.nextToken()));
331 } catch (NumberFormatException nfe) {
332 throw new AWTException("failed to parse hotspot property for cursor: " + name);
333 }
334 final Toolkit toolkit = Toolkit.getDefaultToolkit();
335 final String file = RESOURCE_PREFIX + fileName;
336 final InputStream in = AccessController.doPrivileged(
337 (PrivilegedAction<InputStream>) () -> {
338 return Cursor.class.getResourceAsStream(file);
339 });
340 try (in) {
341 ByteArrayOutputStream baos = new ByteArrayOutputStream();
342 in.transferTo(baos);
343 Image image = toolkit.createImage(baos.toByteArray());
344 cursor = toolkit.createCustomCursor(image, hotPoint, localized);
345 } catch (Exception e) {
346 throw new AWTException(
347 "Exception: " + e.getClass() + " " + e.getMessage() +
348 " occurred while creating cursor " + name);
349 }
350
351 if (cursor == null) {
352 if (log.isLoggable(PlatformLogger.Level.FINER)) {
353 log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
354 }
355 } else {
356 systemCustomCursors.put(name, cursor);
357 }
358 }
359
360 return cursor;
361 }
362
363 /**
364 * Return the system default cursor.
365 *
366 * @return the default cursor
367 */
368 public static Cursor getDefaultCursor() {
369 return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
370 }
371
372 /**
373 * Creates a new cursor object with the specified type.
374 * @param type the type of cursor
375 * @throws IllegalArgumentException if the specified cursor type
376 * is invalid
377 */
378 @ConstructorProperties({"type"})
379 public Cursor(int type) {
380 if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
381 throw new IllegalArgumentException("illegal cursor type");
382 }
383 this.type = type;
384
385 // Lookup localized name.
386 name = Toolkit.getProperty(cursorProperties[type][0],
387 cursorProperties[type][1]);
388 }
|