180 throws HeadlessException;
181
182 public abstract MenuItemPeer createMenuItem(MenuItem target)
183 throws HeadlessException;
184
185 public abstract CheckboxMenuItemPeer createCheckboxMenuItem(
186 CheckboxMenuItem target)
187 throws HeadlessException;
188
189 public abstract DragSourceContextPeer createDragSourceContextPeer(
190 DragGestureEvent dge)
191 throws InvalidDnDOperationException;
192
193 public abstract TrayIconPeer createTrayIcon(TrayIcon target)
194 throws HeadlessException, AWTException;
195
196 public abstract SystemTrayPeer createSystemTray(SystemTray target);
197
198 public abstract boolean isTraySupported();
199
200 public abstract FontPeer getFontPeer(String name, int style);
201
202 public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
203 throws AWTException;
204
205 public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
206 throws HeadlessException;
207
208 /**
209 * The AWT lock is typically only used on Unix platforms to synchronize
210 * access to Xlib, OpenGL, etc. However, these methods are implemented
211 * in SunToolkit so that they can be called from shared code (e.g.
212 * from the OGL pipeline) or from the X11 pipeline regardless of whether
213 * XToolkit or MToolkit is currently in use. There are native macros
214 * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
215 * methods is changed, make sure it is compatible with the native macros.
216 *
217 * Note: The following methods (awtLock(), awtUnlock(), etc) should be
218 * used in place of:
219 * synchronized (getAWTLock()) {
288 // return correct values
289 AppContext appContext = new AppContext(threadGroup);
290
291 EventQueue eventQueue;
292 String eqName = System.getProperty("AWT.EventQueueClass",
293 "java.awt.EventQueue");
294 try {
295 eventQueue = (EventQueue)Class.forName(eqName).newInstance();
296 } catch (Exception e) {
297 System.err.println("Failed loading " + eqName + ": " + e);
298 eventQueue = new EventQueue();
299 }
300 appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
301
302 PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
303 appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
304
305 return appContext;
306 }
307
308 public static Field getField(final Class klass, final String fieldName) {
309 return AccessController.doPrivileged(new PrivilegedAction<Field>() {
310 public Field run() {
311 try {
312 Field field = klass.getDeclaredField(fieldName);
313 assert (field != null);
314 field.setAccessible(true);
315 return field;
316 } catch (SecurityException e) {
317 assert false;
318 } catch (NoSuchFieldException e) {
319 assert false;
320 }
321 return null;
322 }//run
323 });
324 }
325
326 static void wakeupEventQueue(EventQueue q, boolean isShutdown){
327 if (wakeupMethod == null){
328 wakeupMethod = (Method)AccessController.doPrivileged(new PrivilegedAction(){
329 public Object run(){
330 try {
331 Method method = EventQueue.class.getDeclaredMethod("wakeup",new Class [] {Boolean.TYPE} );
332 if (method != null) {
333 method.setAccessible(true);
334 }
335 return method;
336 } catch (NoSuchMethodException e) {
337 assert false;
338 } catch (SecurityException e) {
339 assert false;
340 }
341 return null;
342 }//run
343 });
344 }
345 try{
346 if (wakeupMethod != null){
347 wakeupMethod.invoke(q, new Object[]{Boolean.valueOf(isShutdown)});
348 }
349 } catch (InvocationTargetException e){
369 }
370
371 protected static void targetCreatedPeer(Object target, Object peer) {
372 if (target != null && peer != null &&
373 !GraphicsEnvironment.isHeadless())
374 {
375 AWTAutoShutdown.getInstance().registerPeer(target, peer);
376 }
377 }
378
379 protected static void targetDisposedPeer(Object target, Object peer) {
380 if (target != null && peer != null &&
381 !GraphicsEnvironment.isHeadless())
382 {
383 AWTAutoShutdown.getInstance().unregisterPeer(target, peer);
384 }
385 }
386
387 // Maps from non-Component/MenuComponent to AppContext.
388 // WeakHashMap<Component,AppContext>
389 private static final Map appContextMap =
390 Collections.synchronizedMap(new WeakHashMap());
391
392 /**
393 * Sets the appContext field of target. If target is not a Component or
394 * MenuComponent, this returns false.
395 */
396 private static boolean setAppContext(Object target,
397 AppContext context) {
398 if (target instanceof Component) {
399 AWTAccessor.getComponentAccessor().
400 setAppContext((Component)target, context);
401 } else if (target instanceof MenuComponent) {
402 AWTAccessor.getMenuComponentAccessor().
403 setAppContext((MenuComponent)target, context);
404 } else {
405 return false;
406 }
407 return true;
408 }
409
410 /**
420 getAppContext((MenuComponent)target);
421 } else {
422 return null;
423 }
424 }
425
426 /*
427 * Fetch the AppContext associated with the given target.
428 * This can be used to determine things like which EventQueue
429 * to use for posting events to a Component. If the target is
430 * null or the target can't be found, a null with be returned.
431 */
432 public static AppContext targetToAppContext(Object target) {
433 if (target == null || GraphicsEnvironment.isHeadless()) {
434 return null;
435 }
436 AppContext context = getAppContext(target);
437 if (context == null) {
438 // target is not a Component/MenuComponent, try the
439 // appContextMap.
440 context = (AppContext)appContextMap.get(target);
441 }
442 return context;
443 }
444
445 /**
446 * Sets the synchronous status of focus requests on lightweight
447 * components in the specified window to the specified value.
448 * If the boolean parameter is <code>true</code> then the focus
449 * requests on lightweight components will be performed
450 * synchronously, if it is <code>false</code>, then asynchronously.
451 * By default, all windows have their lightweight request status
452 * set to asynchronous.
453 * <p>
454 * The application can only set the status of lightweight focus
455 * requests to synchronous for any of its windows if it doesn't
456 * perform focus transfers between different heavyweight containers.
457 * In this case the observable focus behaviour is the same as with
458 * asynchronous status.
459 * <p>
460 * If the application performs focus transfer between different
502 }
503 } else if (policyName.startsWith("javax.swing.")) {
504 if (isSwingCont) {
505 // New Swing's policy
506 } else {
507 defaultPolicy = new DefaultFocusTraversalPolicy();
508 }
509 }
510 } else {
511 // Policy is default, use different default policy for swing
512 if (isSwingCont) {
513 defaultPolicy = createLayoutPolicy();
514 }
515 }
516 cont.setFocusTraversalPolicy(defaultPolicy);
517 }
518
519 private static FocusTraversalPolicy createLayoutPolicy() {
520 FocusTraversalPolicy policy = null;
521 try {
522 Class layoutPolicyClass =
523 Class.forName("javax.swing.LayoutFocusTraversalPolicy");
524 policy = (FocusTraversalPolicy) layoutPolicyClass.newInstance();
525 }
526 catch (ClassNotFoundException e) {
527 assert false;
528 }
529 catch (InstantiationException e) {
530 assert false;
531 }
532 catch (IllegalAccessException e) {
533 assert false;
534 }
535
536 return policy;
537 }
538
539 /*
540 * Insert a mapping from target to AppContext, for later retrieval
541 * via targetToAppContext() above.
542 */
543 public static void insertTargetMapping(Object target, AppContext appContext) {
544 if (!GraphicsEnvironment.isHeadless()) {
625 return postEventQueue.noEvents();
626 } else {
627 return true;
628 }
629 }
630
631 /*
632 * Execute a chunk of code on the Java event handler thread for the
633 * given target. Does not wait for the execution to occur before
634 * returning to the caller.
635 */
636 public static void executeOnEventHandlerThread(Object target,
637 Runnable runnable) {
638 executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
639 }
640
641 /*
642 * Fixed 5064013: the InvocationEvent time should be equals
643 * the time of the ActionEvent
644 */
645 public static void executeOnEventHandlerThread(Object target,
646 Runnable runnable,
647 final long when) {
648 executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT){
649 public long getWhen(){
650 return when;
651 }
652 });
653 }
654
655 /*
656 * Execute a chunk of code on the Java event handler thread for the
657 * given target. Does not wait for the execution to occur before
658 * returning to the caller.
659 */
660 public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
661 postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
662 }
663
664 /*
665 * Execute a chunk of code on the Java event handler thread. The
666 * method takes into account provided AppContext and sets
667 * <code>SunToolkit.getDefaultToolkit()</code> as a target of the
668 * event. See 6451487 for detailes.
669 * Does not wait for the execution to occur before returning to
710 /*
711 * Returns true if the calling thread is the event dispatch thread
712 * contained within AppContext which associated with the given target.
713 * Use this call to ensure that a given task is being executed
714 * (or not being) on the event dispatch thread for the given target.
715 */
716 public static boolean isDispatchThreadForAppContext(Object target) {
717 AppContext appContext = targetToAppContext(target);
718 EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
719
720 AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
721 return accessor.isDispatchThreadImpl(eq);
722 }
723
724 public Dimension getScreenSize() {
725 return new Dimension(getScreenWidth(), getScreenHeight());
726 }
727 protected abstract int getScreenWidth();
728 protected abstract int getScreenHeight();
729
730 public FontMetrics getFontMetrics(Font font) {
731 return FontDesignMetrics.getMetrics(font);
732 }
733
734 public String[] getFontList() {
735 String[] hardwiredFontList = {
736 Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED,
737 Font.DIALOG_INPUT
738
739 // -- Obsolete font names from 1.0.2. It was decided that
740 // -- getFontList should not return these old names:
741 // "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
742 };
743 return hardwiredFontList;
744 }
745
746 public PanelPeer createPanel(Panel target) {
747 return (PanelPeer)createComponent(target);
748 }
749
750 public CanvasPeer createCanvas(Canvas target) {
751 return (CanvasPeer)createComponent(target);
752 }
753
1139 public Window createInputMethodWindow(String title, InputContext context) {
1140 return new sun.awt.im.SimpleInputMethodWindow(title, context);
1141 }
1142
1143 /**
1144 * Returns whether enableInputMethods should be set to true for peered
1145 * TextComponent instances on this platform. False by default.
1146 */
1147 public boolean enableInputMethodsForTextComponent() {
1148 return false;
1149 }
1150
1151 private static Locale startupLocale = null;
1152
1153 /**
1154 * Returns the locale in which the runtime was started.
1155 */
1156 public static Locale getStartupLocale() {
1157 if (startupLocale == null) {
1158 String language, region, country, variant;
1159 language = (String) AccessController.doPrivileged(
1160 new GetPropertyAction("user.language", "en"));
1161 // for compatibility, check for old user.region property
1162 region = (String) AccessController.doPrivileged(
1163 new GetPropertyAction("user.region"));
1164 if (region != null) {
1165 // region can be of form country, country_variant, or _variant
1166 int i = region.indexOf('_');
1167 if (i >= 0) {
1168 country = region.substring(0, i);
1169 variant = region.substring(i + 1);
1170 } else {
1171 country = region;
1172 variant = "";
1173 }
1174 } else {
1175 country = (String) AccessController.doPrivileged(
1176 new GetPropertyAction("user.country", ""));
1177 variant = (String) AccessController.doPrivileged(
1178 new GetPropertyAction("user.variant", ""));
1179 }
1180 startupLocale = new Locale(language, country, variant);
1181 }
1182 return startupLocale;
1183 }
1184
1185 /**
1186 * Returns the default keyboard locale of the underlying operating system
1187 */
1188 public Locale getDefaultKeyboardLocale() {
1189 return getStartupLocale();
1190 }
1191
1192 private static String dataTransfererClassName = null;
1193
1194 protected static void setDataTransfererClassName(String className) {
1195 dataTransfererClassName = className;
1196 }
1197
1237 return null;
1238 }
1239 }
1240
1241 private static DefaultMouseInfoPeer mPeer = null;
1242
1243 protected synchronized MouseInfoPeer getMouseInfoPeer() {
1244 if (mPeer == null) {
1245 mPeer = new DefaultMouseInfoPeer();
1246 }
1247 return mPeer;
1248 }
1249
1250
1251 /**
1252 * Returns whether default toolkit needs the support of the xembed
1253 * from embedding host(if any).
1254 * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1255 */
1256 public static boolean needsXEmbed() {
1257 String noxembed = (String) AccessController.
1258 doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false"));
1259 if ("true".equals(noxembed)) {
1260 return false;
1261 }
1262
1263 Toolkit tk = Toolkit.getDefaultToolkit();
1264 if (tk instanceof SunToolkit) {
1265 // SunToolkit descendants should override this method to specify
1266 // concrete behavior
1267 return ((SunToolkit)tk).needsXEmbedImpl();
1268 } else {
1269 // Non-SunToolkit doubtly might support XEmbed
1270 return false;
1271 }
1272 }
1273
1274 /**
1275 * Returns whether this toolkit needs the support of the xembed
1276 * from embedding host(if any).
1277 * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1449 public static boolean isLightweightOrUnknown(Component comp) {
1450 if (comp.isLightweight()
1451 || !(getDefaultToolkit() instanceof SunToolkit))
1452 {
1453 return true;
1454 }
1455 return !(comp instanceof Button
1456 || comp instanceof Canvas
1457 || comp instanceof Checkbox
1458 || comp instanceof Choice
1459 || comp instanceof Label
1460 || comp instanceof java.awt.List
1461 || comp instanceof Panel
1462 || comp instanceof Scrollbar
1463 || comp instanceof ScrollPane
1464 || comp instanceof TextArea
1465 || comp instanceof TextField
1466 || comp instanceof Window);
1467 }
1468
1469 public static Method getMethod(final Class clz, final String methodName, final Class[] params) {
1470 Method res = null;
1471 try {
1472 res = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
1473 public Method run() throws Exception {
1474 Method m = clz.getDeclaredMethod(methodName, params);
1475 m.setAccessible(true);
1476 return m;
1477 }
1478 });
1479 } catch (PrivilegedActionException ex) {
1480 ex.printStackTrace();
1481 }
1482 return res;
1483 }
1484
1485 public static class OperationTimedOut extends RuntimeException {
1486 public OperationTimedOut(String msg) {
1487 super(msg);
1488 }
1489 public OperationTimedOut() {
1490 }
1491 }
1492 public static class InfiniteLoop extends RuntimeException {
1493 }
1494
1495 public static class IllegalThreadException extends RuntimeException {
1496 public IllegalThreadException(String msg) {
1497 super(msg);
1498 }
1499 public IllegalThreadException() {
1500 }
1501 }
1502
1503 public static final int DEFAULT_WAIT_TIME = 10000;
1504 private static final int MAX_ITERS = 20;
1505 private static final int MIN_ITERS = 0;
1506 private static final int MINIMAL_EDELAY = 0;
1507
1508 /**
1509 * Parameterless version of realsync which uses default timout (see DEFAUL_WAIT_TIME).
1510 */
1511 public void realSync() throws OperationTimedOut, InfiniteLoop {
1512 realSync(DEFAULT_WAIT_TIME);
1513 }
1514
1631 synchronized(SunToolkit.class) {
1632 if (eqNoEvents == null) {
1633 eqNoEvents = getMethod(java.awt.EventQueue.class, "noEvents", null);
1634 }
1635 }
1636 try {
1637 return (Boolean)eqNoEvents.invoke(queue);
1638 } catch (Exception e) {
1639 e.printStackTrace();
1640 return false;
1641 }
1642 }
1643
1644 /**
1645 * Waits for the Java event queue to empty. Ensures that all
1646 * events are processed (including paint events), and that if
1647 * recursive events were generated, they are also processed.
1648 * Should return <code>true</code> if more processing is
1649 * necessary, <code>false</code> otherwise.
1650 */
1651 protected final boolean waitForIdle(final long timeout) {
1652 flushPendingEvents();
1653 boolean queueWasEmpty = isEQEmpty();
1654 queueEmpty = false;
1655 eventDispatched = false;
1656 synchronized(waitLock) {
1657 postEvent(AppContext.getAppContext(),
1658 new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
1659 public void dispatch() {
1660 // Here we block EDT. It could have some
1661 // events, it should have dispatched them by
1662 // now. So native requests could have been
1663 // generated. First, dispatch them. Then,
1664 // flush Java events again.
1665 int iters = 0;
1666 while (iters < MIN_ITERS) {
1667 syncNativeQueue(timeout);
1668 iters++;
1669 }
1670 while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
1814 } else {
1815 return null;
1816 }
1817 }
1818
1819 /* This method determines whether to use the system font settings,
1820 * or ignore them if a L&F has specified they should be ignored, or
1821 * to override both of these with a system property specified value.
1822 * If the toolkit isn't a SunToolkit, (eg may be headless) then that
1823 * system property isn't applied as desktop properties are considered
1824 * to be inapplicable in that case. In that headless case although
1825 * this method will return "true" the toolkit will return a null map.
1826 */
1827 private static boolean useSystemAAFontSettings() {
1828 if (!checkedSystemAAFontSettings) {
1829 useSystemAAFontSettings = true; /* initially set this true */
1830 String systemAAFonts = null;
1831 Toolkit tk = Toolkit.getDefaultToolkit();
1832 if (tk instanceof SunToolkit) {
1833 systemAAFonts =
1834 (String)AccessController.doPrivileged(
1835 new GetPropertyAction("awt.useSystemAAFontSettings"));
1836 }
1837 if (systemAAFonts != null) {
1838 useSystemAAFontSettings =
1839 Boolean.valueOf(systemAAFonts).booleanValue();
1840 /* If it is anything other than "true", then it may be
1841 * a hint name , or it may be "off, "default", etc.
1842 */
1843 if (!useSystemAAFontSettings) {
1844 desktopFontHints = getDesktopAAHintsByName(systemAAFonts);
1845 }
1846 }
1847 /* If its still true, apply the extra condition */
1848 if (useSystemAAFontSettings) {
1849 useSystemAAFontSettings = lastExtraCondition;
1850 }
1851 checkedSystemAAFontSettings = true;
1852 }
1853 return useSystemAAFontSettings;
1854 }
1881 * its harmless.
1882 */
1883 return (RenderingHints)(desktopFontHints.clone());
1884 } else {
1885 return null;
1886 }
1887 }
1888
1889
1890 public abstract boolean isDesktopSupported();
1891
1892 /*
1893 * consumeNextKeyTyped() method is not currently used,
1894 * however Swing could use it in the future.
1895 */
1896 private static Method consumeNextKeyTypedMethod = null;
1897 public static synchronized void consumeNextKeyTyped(KeyEvent keyEvent) {
1898 if (consumeNextKeyTypedMethod == null) {
1899 consumeNextKeyTypedMethod = getMethod(DefaultKeyboardFocusManager.class,
1900 "consumeNextKeyTyped",
1901 new Class[] {KeyEvent.class});
1902 }
1903 try {
1904 consumeNextKeyTypedMethod.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(),
1905 keyEvent);
1906 } catch (IllegalAccessException iae) {
1907 iae.printStackTrace();
1908 } catch (InvocationTargetException ite) {
1909 ite.printStackTrace();
1910 }
1911 }
1912
1913 protected static void dumpPeers(final PlatformLogger aLog) {
1914 AWTAutoShutdown.getInstance().dumpPeers(aLog);
1915 }
1916
1917 /**
1918 * Returns the <code>Window</code> ancestor of the component <code>comp</code>.
1919 * @return Window ancestor of the component or component by itself if it is Window;
1920 * null, if component is not a part of window hierarchy
1921 */
1922 public static Window getContainingWindow(Component comp) {
1923 while (comp != null && !(comp instanceof Window)) {
1924 comp = comp.getParent();
1925 }
1926 return (Window)comp;
1927 }
1928
1929 /**
1930 * Returns the value of the system property indicated by the specified key.
1931 */
1932 public static String getSystemProperty(final String key) {
1933 return (String)AccessController.doPrivileged(new PrivilegedAction() {
1934 public Object run() {
1935 return System.getProperty(key);
1936 }
1937 });
1938 }
1939
1940 /**
1941 * Returns the boolean value of the system property indicated by the specified key.
1942 */
1943 protected static Boolean getBooleanSystemProperty(String key) {
1944 return Boolean.valueOf(AccessController.
1945 doPrivileged(new GetBooleanAction(key)));
1946 }
1947
1948 private static Boolean sunAwtDisableMixing = null;
1949
1950 /**
1951 * Returns the value of "sun.awt.disableMixing" property. Default
1952 * value is {@code false}.
1953 */
1954 public synchronized static boolean getSunAwtDisableMixing() {
1955 if (sunAwtDisableMixing == null) {
1956 sunAwtDisableMixing = getBooleanSystemProperty("sun.awt.disableMixing");
1957 }
1958 return sunAwtDisableMixing.booleanValue();
1959 }
1960
1961 /**
1962 * Returns true if the native GTK libraries are available. The
1963 * default implementation returns false, but UNIXToolkit overrides this
1964 * method to provide a more specific answer.
1965 */
1998 * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
1999 */
2000 public static boolean isContainingTopLevelOpaque(Component c) {
2001 Window w = getContainingWindow(c);
2002 return w != null && w.isOpaque();
2003 }
2004
2005 /**
2006 * Returns whether or not a containing top level window for the passed
2007 * component is
2008 * {@link GraphicsDevice.WindowTranslucency#TRANSLUCENT TRANSLUCENT}.
2009 *
2010 * @param c a Component which toplevel's to check
2011 * @return {@code true} if the passed component is not null and has a
2012 * containing toplevel window which has opacity less than
2013 * 1.0f (which means that it is translucent), {@code false} otherwise
2014 * @see GraphicsDevice.WindowTranslucency#TRANSLUCENT
2015 */
2016 public static boolean isContainingTopLevelTranslucent(Component c) {
2017 Window w = getContainingWindow(c);
2018 return w != null && ((Window)w).getOpacity() < 1.0f;
2019 }
2020
2021 /**
2022 * Returns whether the native system requires using the peer.updateWindow()
2023 * method to update the contents of a non-opaque window, or if usual
2024 * painting procedures are sufficient. The default return value covers
2025 * the X11 systems. On MS Windows this method is overriden in WToolkit
2026 * to return true.
2027 */
2028 public boolean needUpdateWindow() {
2029 return false;
2030 }
2031
2032 /**
2033 * Descendants of the SunToolkit should override and put their own logic here.
2034 */
2035 public int getNumberOfButtons(){
2036 return 3;
2037 }
2038
2040 * Checks that the given object implements/extends the given
2041 * interface/class.
2042 *
2043 * Note that using the instanceof operator causes a class to be loaded.
2044 * Using this method doesn't load a class and it can be used instead of
2045 * the instanceof operator for performance reasons.
2046 *
2047 * @param obj Object to be checked
2048 * @param type The name of the interface/class. Must be
2049 * fully-qualified interface/class name.
2050 * @return true, if this object implements/extends the given
2051 * interface/class, false, otherwise, or if obj or type is null
2052 */
2053 public static boolean isInstanceOf(Object obj, String type) {
2054 if (obj == null) return false;
2055 if (type == null) return false;
2056
2057 return isInstanceOf(obj.getClass(), type);
2058 }
2059
2060 private static boolean isInstanceOf(Class cls, String type) {
2061 if (cls == null) return false;
2062
2063 if (cls.getName().equals(type)) {
2064 return true;
2065 }
2066
2067 for (Class c : cls.getInterfaces()) {
2068 if (c.getName().equals(type)) {
2069 return true;
2070 }
2071 }
2072 return isInstanceOf(cls.getSuperclass(), type);
2073 }
2074
2075 ///////////////////////////////////////////////////////////////////////////
2076 //
2077 // The following methods help set and identify whether a particular
2078 // AWTEvent object was produced by the system or by user code. As of this
2079 // writing the only consumer is the Java Plug-In, although this information
2080 // could be useful to more clients and probably should be formalized in
2081 // the public API.
2082 //
2083 ///////////////////////////////////////////////////////////////////////////
2084
2085 public static void setSystemGenerated(AWTEvent e) {
2086 AWTAccessor.getAWTEventAccessor().setSystemGenerated(e);
2087 }
|
180 throws HeadlessException;
181
182 public abstract MenuItemPeer createMenuItem(MenuItem target)
183 throws HeadlessException;
184
185 public abstract CheckboxMenuItemPeer createCheckboxMenuItem(
186 CheckboxMenuItem target)
187 throws HeadlessException;
188
189 public abstract DragSourceContextPeer createDragSourceContextPeer(
190 DragGestureEvent dge)
191 throws InvalidDnDOperationException;
192
193 public abstract TrayIconPeer createTrayIcon(TrayIcon target)
194 throws HeadlessException, AWTException;
195
196 public abstract SystemTrayPeer createSystemTray(SystemTray target);
197
198 public abstract boolean isTraySupported();
199
200 @SuppressWarnings("deprecation")
201 public abstract FontPeer getFontPeer(String name, int style);
202
203 public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
204 throws AWTException;
205
206 public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
207 throws HeadlessException;
208
209 /**
210 * The AWT lock is typically only used on Unix platforms to synchronize
211 * access to Xlib, OpenGL, etc. However, these methods are implemented
212 * in SunToolkit so that they can be called from shared code (e.g.
213 * from the OGL pipeline) or from the X11 pipeline regardless of whether
214 * XToolkit or MToolkit is currently in use. There are native macros
215 * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
216 * methods is changed, make sure it is compatible with the native macros.
217 *
218 * Note: The following methods (awtLock(), awtUnlock(), etc) should be
219 * used in place of:
220 * synchronized (getAWTLock()) {
289 // return correct values
290 AppContext appContext = new AppContext(threadGroup);
291
292 EventQueue eventQueue;
293 String eqName = System.getProperty("AWT.EventQueueClass",
294 "java.awt.EventQueue");
295 try {
296 eventQueue = (EventQueue)Class.forName(eqName).newInstance();
297 } catch (Exception e) {
298 System.err.println("Failed loading " + eqName + ": " + e);
299 eventQueue = new EventQueue();
300 }
301 appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
302
303 PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
304 appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
305
306 return appContext;
307 }
308
309 public static Field getField(final Class<?> klass, final String fieldName) {
310 return AccessController.doPrivileged(new PrivilegedAction<Field>() {
311 public Field run() {
312 try {
313 Field field = klass.getDeclaredField(fieldName);
314 assert (field != null);
315 field.setAccessible(true);
316 return field;
317 } catch (SecurityException e) {
318 assert false;
319 } catch (NoSuchFieldException e) {
320 assert false;
321 }
322 return null;
323 }//run
324 });
325 }
326
327 static void wakeupEventQueue(EventQueue q, boolean isShutdown){
328 if (wakeupMethod == null){
329 wakeupMethod = AccessController.doPrivileged(new PrivilegedAction<Method>() {
330 public Method run() {
331 try {
332 Method method = EventQueue.class.getDeclaredMethod("wakeup",new Class [] {Boolean.TYPE} );
333 if (method != null) {
334 method.setAccessible(true);
335 }
336 return method;
337 } catch (NoSuchMethodException e) {
338 assert false;
339 } catch (SecurityException e) {
340 assert false;
341 }
342 return null;
343 }//run
344 });
345 }
346 try{
347 if (wakeupMethod != null){
348 wakeupMethod.invoke(q, new Object[]{Boolean.valueOf(isShutdown)});
349 }
350 } catch (InvocationTargetException e){
370 }
371
372 protected static void targetCreatedPeer(Object target, Object peer) {
373 if (target != null && peer != null &&
374 !GraphicsEnvironment.isHeadless())
375 {
376 AWTAutoShutdown.getInstance().registerPeer(target, peer);
377 }
378 }
379
380 protected static void targetDisposedPeer(Object target, Object peer) {
381 if (target != null && peer != null &&
382 !GraphicsEnvironment.isHeadless())
383 {
384 AWTAutoShutdown.getInstance().unregisterPeer(target, peer);
385 }
386 }
387
388 // Maps from non-Component/MenuComponent to AppContext.
389 // WeakHashMap<Component,AppContext>
390 private static final Map<Object, AppContext> appContextMap =
391 Collections.synchronizedMap(new WeakHashMap<Object, AppContext>());
392
393 /**
394 * Sets the appContext field of target. If target is not a Component or
395 * MenuComponent, this returns false.
396 */
397 private static boolean setAppContext(Object target,
398 AppContext context) {
399 if (target instanceof Component) {
400 AWTAccessor.getComponentAccessor().
401 setAppContext((Component)target, context);
402 } else if (target instanceof MenuComponent) {
403 AWTAccessor.getMenuComponentAccessor().
404 setAppContext((MenuComponent)target, context);
405 } else {
406 return false;
407 }
408 return true;
409 }
410
411 /**
421 getAppContext((MenuComponent)target);
422 } else {
423 return null;
424 }
425 }
426
427 /*
428 * Fetch the AppContext associated with the given target.
429 * This can be used to determine things like which EventQueue
430 * to use for posting events to a Component. If the target is
431 * null or the target can't be found, a null with be returned.
432 */
433 public static AppContext targetToAppContext(Object target) {
434 if (target == null || GraphicsEnvironment.isHeadless()) {
435 return null;
436 }
437 AppContext context = getAppContext(target);
438 if (context == null) {
439 // target is not a Component/MenuComponent, try the
440 // appContextMap.
441 context = appContextMap.get(target);
442 }
443 return context;
444 }
445
446 /**
447 * Sets the synchronous status of focus requests on lightweight
448 * components in the specified window to the specified value.
449 * If the boolean parameter is <code>true</code> then the focus
450 * requests on lightweight components will be performed
451 * synchronously, if it is <code>false</code>, then asynchronously.
452 * By default, all windows have their lightweight request status
453 * set to asynchronous.
454 * <p>
455 * The application can only set the status of lightweight focus
456 * requests to synchronous for any of its windows if it doesn't
457 * perform focus transfers between different heavyweight containers.
458 * In this case the observable focus behaviour is the same as with
459 * asynchronous status.
460 * <p>
461 * If the application performs focus transfer between different
503 }
504 } else if (policyName.startsWith("javax.swing.")) {
505 if (isSwingCont) {
506 // New Swing's policy
507 } else {
508 defaultPolicy = new DefaultFocusTraversalPolicy();
509 }
510 }
511 } else {
512 // Policy is default, use different default policy for swing
513 if (isSwingCont) {
514 defaultPolicy = createLayoutPolicy();
515 }
516 }
517 cont.setFocusTraversalPolicy(defaultPolicy);
518 }
519
520 private static FocusTraversalPolicy createLayoutPolicy() {
521 FocusTraversalPolicy policy = null;
522 try {
523 Class<?> layoutPolicyClass =
524 Class.forName("javax.swing.LayoutFocusTraversalPolicy");
525 policy = (FocusTraversalPolicy)layoutPolicyClass.newInstance();
526 }
527 catch (ClassNotFoundException e) {
528 assert false;
529 }
530 catch (InstantiationException e) {
531 assert false;
532 }
533 catch (IllegalAccessException e) {
534 assert false;
535 }
536
537 return policy;
538 }
539
540 /*
541 * Insert a mapping from target to AppContext, for later retrieval
542 * via targetToAppContext() above.
543 */
544 public static void insertTargetMapping(Object target, AppContext appContext) {
545 if (!GraphicsEnvironment.isHeadless()) {
626 return postEventQueue.noEvents();
627 } else {
628 return true;
629 }
630 }
631
632 /*
633 * Execute a chunk of code on the Java event handler thread for the
634 * given target. Does not wait for the execution to occur before
635 * returning to the caller.
636 */
637 public static void executeOnEventHandlerThread(Object target,
638 Runnable runnable) {
639 executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
640 }
641
642 /*
643 * Fixed 5064013: the InvocationEvent time should be equals
644 * the time of the ActionEvent
645 */
646 @SuppressWarnings("serial")
647 public static void executeOnEventHandlerThread(Object target,
648 Runnable runnable,
649 final long when) {
650 executeOnEventHandlerThread(
651 new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT) {
652 public long getWhen() {
653 return when;
654 }
655 });
656 }
657
658 /*
659 * Execute a chunk of code on the Java event handler thread for the
660 * given target. Does not wait for the execution to occur before
661 * returning to the caller.
662 */
663 public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
664 postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
665 }
666
667 /*
668 * Execute a chunk of code on the Java event handler thread. The
669 * method takes into account provided AppContext and sets
670 * <code>SunToolkit.getDefaultToolkit()</code> as a target of the
671 * event. See 6451487 for detailes.
672 * Does not wait for the execution to occur before returning to
713 /*
714 * Returns true if the calling thread is the event dispatch thread
715 * contained within AppContext which associated with the given target.
716 * Use this call to ensure that a given task is being executed
717 * (or not being) on the event dispatch thread for the given target.
718 */
719 public static boolean isDispatchThreadForAppContext(Object target) {
720 AppContext appContext = targetToAppContext(target);
721 EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
722
723 AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
724 return accessor.isDispatchThreadImpl(eq);
725 }
726
727 public Dimension getScreenSize() {
728 return new Dimension(getScreenWidth(), getScreenHeight());
729 }
730 protected abstract int getScreenWidth();
731 protected abstract int getScreenHeight();
732
733 @SuppressWarnings("deprecation")
734 public FontMetrics getFontMetrics(Font font) {
735 return FontDesignMetrics.getMetrics(font);
736 }
737
738 @SuppressWarnings("deprecation")
739 public String[] getFontList() {
740 String[] hardwiredFontList = {
741 Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED,
742 Font.DIALOG_INPUT
743
744 // -- Obsolete font names from 1.0.2. It was decided that
745 // -- getFontList should not return these old names:
746 // "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
747 };
748 return hardwiredFontList;
749 }
750
751 public PanelPeer createPanel(Panel target) {
752 return (PanelPeer)createComponent(target);
753 }
754
755 public CanvasPeer createCanvas(Canvas target) {
756 return (CanvasPeer)createComponent(target);
757 }
758
1144 public Window createInputMethodWindow(String title, InputContext context) {
1145 return new sun.awt.im.SimpleInputMethodWindow(title, context);
1146 }
1147
1148 /**
1149 * Returns whether enableInputMethods should be set to true for peered
1150 * TextComponent instances on this platform. False by default.
1151 */
1152 public boolean enableInputMethodsForTextComponent() {
1153 return false;
1154 }
1155
1156 private static Locale startupLocale = null;
1157
1158 /**
1159 * Returns the locale in which the runtime was started.
1160 */
1161 public static Locale getStartupLocale() {
1162 if (startupLocale == null) {
1163 String language, region, country, variant;
1164 language = AccessController.doPrivileged(
1165 new GetPropertyAction("user.language", "en"));
1166 // for compatibility, check for old user.region property
1167 region = AccessController.doPrivileged(
1168 new GetPropertyAction("user.region"));
1169 if (region != null) {
1170 // region can be of form country, country_variant, or _variant
1171 int i = region.indexOf('_');
1172 if (i >= 0) {
1173 country = region.substring(0, i);
1174 variant = region.substring(i + 1);
1175 } else {
1176 country = region;
1177 variant = "";
1178 }
1179 } else {
1180 country = AccessController.doPrivileged(
1181 new GetPropertyAction("user.country", ""));
1182 variant = AccessController.doPrivileged(
1183 new GetPropertyAction("user.variant", ""));
1184 }
1185 startupLocale = new Locale(language, country, variant);
1186 }
1187 return startupLocale;
1188 }
1189
1190 /**
1191 * Returns the default keyboard locale of the underlying operating system
1192 */
1193 public Locale getDefaultKeyboardLocale() {
1194 return getStartupLocale();
1195 }
1196
1197 private static String dataTransfererClassName = null;
1198
1199 protected static void setDataTransfererClassName(String className) {
1200 dataTransfererClassName = className;
1201 }
1202
1242 return null;
1243 }
1244 }
1245
1246 private static DefaultMouseInfoPeer mPeer = null;
1247
1248 protected synchronized MouseInfoPeer getMouseInfoPeer() {
1249 if (mPeer == null) {
1250 mPeer = new DefaultMouseInfoPeer();
1251 }
1252 return mPeer;
1253 }
1254
1255
1256 /**
1257 * Returns whether default toolkit needs the support of the xembed
1258 * from embedding host(if any).
1259 * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1260 */
1261 public static boolean needsXEmbed() {
1262 String noxembed = AccessController.
1263 doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false"));
1264 if ("true".equals(noxembed)) {
1265 return false;
1266 }
1267
1268 Toolkit tk = Toolkit.getDefaultToolkit();
1269 if (tk instanceof SunToolkit) {
1270 // SunToolkit descendants should override this method to specify
1271 // concrete behavior
1272 return ((SunToolkit)tk).needsXEmbedImpl();
1273 } else {
1274 // Non-SunToolkit doubtly might support XEmbed
1275 return false;
1276 }
1277 }
1278
1279 /**
1280 * Returns whether this toolkit needs the support of the xembed
1281 * from embedding host(if any).
1282 * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1454 public static boolean isLightweightOrUnknown(Component comp) {
1455 if (comp.isLightweight()
1456 || !(getDefaultToolkit() instanceof SunToolkit))
1457 {
1458 return true;
1459 }
1460 return !(comp instanceof Button
1461 || comp instanceof Canvas
1462 || comp instanceof Checkbox
1463 || comp instanceof Choice
1464 || comp instanceof Label
1465 || comp instanceof java.awt.List
1466 || comp instanceof Panel
1467 || comp instanceof Scrollbar
1468 || comp instanceof ScrollPane
1469 || comp instanceof TextArea
1470 || comp instanceof TextField
1471 || comp instanceof Window);
1472 }
1473
1474 public static Method getMethod(final Class<?> clz, final String methodName, final Class[] params) {
1475 Method res = null;
1476 try {
1477 res = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
1478 public Method run() throws Exception {
1479 Method m = clz.getDeclaredMethod(methodName, params);
1480 m.setAccessible(true);
1481 return m;
1482 }
1483 });
1484 } catch (PrivilegedActionException ex) {
1485 ex.printStackTrace();
1486 }
1487 return res;
1488 }
1489
1490 @SuppressWarnings("serial")
1491 public static class OperationTimedOut extends RuntimeException {
1492 public OperationTimedOut(String msg) {
1493 super(msg);
1494 }
1495 public OperationTimedOut() {
1496 }
1497 }
1498
1499 @SuppressWarnings("serial")
1500 public static class InfiniteLoop extends RuntimeException {
1501 }
1502
1503 @SuppressWarnings("serial")
1504 public static class IllegalThreadException extends RuntimeException {
1505 public IllegalThreadException(String msg) {
1506 super(msg);
1507 }
1508 public IllegalThreadException() {
1509 }
1510 }
1511
1512 public static final int DEFAULT_WAIT_TIME = 10000;
1513 private static final int MAX_ITERS = 20;
1514 private static final int MIN_ITERS = 0;
1515 private static final int MINIMAL_EDELAY = 0;
1516
1517 /**
1518 * Parameterless version of realsync which uses default timout (see DEFAUL_WAIT_TIME).
1519 */
1520 public void realSync() throws OperationTimedOut, InfiniteLoop {
1521 realSync(DEFAULT_WAIT_TIME);
1522 }
1523
1640 synchronized(SunToolkit.class) {
1641 if (eqNoEvents == null) {
1642 eqNoEvents = getMethod(java.awt.EventQueue.class, "noEvents", null);
1643 }
1644 }
1645 try {
1646 return (Boolean)eqNoEvents.invoke(queue);
1647 } catch (Exception e) {
1648 e.printStackTrace();
1649 return false;
1650 }
1651 }
1652
1653 /**
1654 * Waits for the Java event queue to empty. Ensures that all
1655 * events are processed (including paint events), and that if
1656 * recursive events were generated, they are also processed.
1657 * Should return <code>true</code> if more processing is
1658 * necessary, <code>false</code> otherwise.
1659 */
1660 @SuppressWarnings("serial")
1661 protected final boolean waitForIdle(final long timeout) {
1662 flushPendingEvents();
1663 boolean queueWasEmpty = isEQEmpty();
1664 queueEmpty = false;
1665 eventDispatched = false;
1666 synchronized(waitLock) {
1667 postEvent(AppContext.getAppContext(),
1668 new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
1669 public void dispatch() {
1670 // Here we block EDT. It could have some
1671 // events, it should have dispatched them by
1672 // now. So native requests could have been
1673 // generated. First, dispatch them. Then,
1674 // flush Java events again.
1675 int iters = 0;
1676 while (iters < MIN_ITERS) {
1677 syncNativeQueue(timeout);
1678 iters++;
1679 }
1680 while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
1824 } else {
1825 return null;
1826 }
1827 }
1828
1829 /* This method determines whether to use the system font settings,
1830 * or ignore them if a L&F has specified they should be ignored, or
1831 * to override both of these with a system property specified value.
1832 * If the toolkit isn't a SunToolkit, (eg may be headless) then that
1833 * system property isn't applied as desktop properties are considered
1834 * to be inapplicable in that case. In that headless case although
1835 * this method will return "true" the toolkit will return a null map.
1836 */
1837 private static boolean useSystemAAFontSettings() {
1838 if (!checkedSystemAAFontSettings) {
1839 useSystemAAFontSettings = true; /* initially set this true */
1840 String systemAAFonts = null;
1841 Toolkit tk = Toolkit.getDefaultToolkit();
1842 if (tk instanceof SunToolkit) {
1843 systemAAFonts =
1844 AccessController.doPrivileged(
1845 new GetPropertyAction("awt.useSystemAAFontSettings"));
1846 }
1847 if (systemAAFonts != null) {
1848 useSystemAAFontSettings =
1849 Boolean.valueOf(systemAAFonts).booleanValue();
1850 /* If it is anything other than "true", then it may be
1851 * a hint name , or it may be "off, "default", etc.
1852 */
1853 if (!useSystemAAFontSettings) {
1854 desktopFontHints = getDesktopAAHintsByName(systemAAFonts);
1855 }
1856 }
1857 /* If its still true, apply the extra condition */
1858 if (useSystemAAFontSettings) {
1859 useSystemAAFontSettings = lastExtraCondition;
1860 }
1861 checkedSystemAAFontSettings = true;
1862 }
1863 return useSystemAAFontSettings;
1864 }
1891 * its harmless.
1892 */
1893 return (RenderingHints)(desktopFontHints.clone());
1894 } else {
1895 return null;
1896 }
1897 }
1898
1899
1900 public abstract boolean isDesktopSupported();
1901
1902 /*
1903 * consumeNextKeyTyped() method is not currently used,
1904 * however Swing could use it in the future.
1905 */
1906 private static Method consumeNextKeyTypedMethod = null;
1907 public static synchronized void consumeNextKeyTyped(KeyEvent keyEvent) {
1908 if (consumeNextKeyTypedMethod == null) {
1909 consumeNextKeyTypedMethod = getMethod(DefaultKeyboardFocusManager.class,
1910 "consumeNextKeyTyped",
1911 new Class<?>[] {KeyEvent.class});
1912 }
1913 try {
1914 consumeNextKeyTypedMethod.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(),
1915 keyEvent);
1916 } catch (IllegalAccessException iae) {
1917 iae.printStackTrace();
1918 } catch (InvocationTargetException ite) {
1919 ite.printStackTrace();
1920 }
1921 }
1922
1923 protected static void dumpPeers(final PlatformLogger aLog) {
1924 AWTAutoShutdown.getInstance().dumpPeers(aLog);
1925 }
1926
1927 /**
1928 * Returns the <code>Window</code> ancestor of the component <code>comp</code>.
1929 * @return Window ancestor of the component or component by itself if it is Window;
1930 * null, if component is not a part of window hierarchy
1931 */
1932 public static Window getContainingWindow(Component comp) {
1933 while (comp != null && !(comp instanceof Window)) {
1934 comp = comp.getParent();
1935 }
1936 return (Window)comp;
1937 }
1938
1939 /**
1940 * Returns the value of the system property indicated by the specified key.
1941 */
1942 public static String getSystemProperty(final String key) {
1943 return AccessController.doPrivileged(new PrivilegedAction<String>() {
1944 public String run() {
1945 return System.getProperty(key);
1946 }
1947 });
1948 }
1949
1950 /**
1951 * Returns the boolean value of the system property indicated by the specified key.
1952 */
1953 protected static Boolean getBooleanSystemProperty(String key) {
1954 return AccessController.doPrivileged(new GetBooleanAction(key));
1955 }
1956
1957 private static Boolean sunAwtDisableMixing = null;
1958
1959 /**
1960 * Returns the value of "sun.awt.disableMixing" property. Default
1961 * value is {@code false}.
1962 */
1963 public synchronized static boolean getSunAwtDisableMixing() {
1964 if (sunAwtDisableMixing == null) {
1965 sunAwtDisableMixing = getBooleanSystemProperty("sun.awt.disableMixing");
1966 }
1967 return sunAwtDisableMixing.booleanValue();
1968 }
1969
1970 /**
1971 * Returns true if the native GTK libraries are available. The
1972 * default implementation returns false, but UNIXToolkit overrides this
1973 * method to provide a more specific answer.
1974 */
2007 * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
2008 */
2009 public static boolean isContainingTopLevelOpaque(Component c) {
2010 Window w = getContainingWindow(c);
2011 return w != null && w.isOpaque();
2012 }
2013
2014 /**
2015 * Returns whether or not a containing top level window for the passed
2016 * component is
2017 * {@link GraphicsDevice.WindowTranslucency#TRANSLUCENT TRANSLUCENT}.
2018 *
2019 * @param c a Component which toplevel's to check
2020 * @return {@code true} if the passed component is not null and has a
2021 * containing toplevel window which has opacity less than
2022 * 1.0f (which means that it is translucent), {@code false} otherwise
2023 * @see GraphicsDevice.WindowTranslucency#TRANSLUCENT
2024 */
2025 public static boolean isContainingTopLevelTranslucent(Component c) {
2026 Window w = getContainingWindow(c);
2027 return w != null && w.getOpacity() < 1.0f;
2028 }
2029
2030 /**
2031 * Returns whether the native system requires using the peer.updateWindow()
2032 * method to update the contents of a non-opaque window, or if usual
2033 * painting procedures are sufficient. The default return value covers
2034 * the X11 systems. On MS Windows this method is overriden in WToolkit
2035 * to return true.
2036 */
2037 public boolean needUpdateWindow() {
2038 return false;
2039 }
2040
2041 /**
2042 * Descendants of the SunToolkit should override and put their own logic here.
2043 */
2044 public int getNumberOfButtons(){
2045 return 3;
2046 }
2047
2049 * Checks that the given object implements/extends the given
2050 * interface/class.
2051 *
2052 * Note that using the instanceof operator causes a class to be loaded.
2053 * Using this method doesn't load a class and it can be used instead of
2054 * the instanceof operator for performance reasons.
2055 *
2056 * @param obj Object to be checked
2057 * @param type The name of the interface/class. Must be
2058 * fully-qualified interface/class name.
2059 * @return true, if this object implements/extends the given
2060 * interface/class, false, otherwise, or if obj or type is null
2061 */
2062 public static boolean isInstanceOf(Object obj, String type) {
2063 if (obj == null) return false;
2064 if (type == null) return false;
2065
2066 return isInstanceOf(obj.getClass(), type);
2067 }
2068
2069 private static boolean isInstanceOf(Class<?> cls, String type) {
2070 if (cls == null) return false;
2071
2072 if (cls.getName().equals(type)) {
2073 return true;
2074 }
2075
2076 for (Class<?> c : cls.getInterfaces()) {
2077 if (c.getName().equals(type)) {
2078 return true;
2079 }
2080 }
2081 return isInstanceOf(cls.getSuperclass(), type);
2082 }
2083
2084 ///////////////////////////////////////////////////////////////////////////
2085 //
2086 // The following methods help set and identify whether a particular
2087 // AWTEvent object was produced by the system or by user code. As of this
2088 // writing the only consumer is the Java Plug-In, although this information
2089 // could be useful to more clients and probably should be formalized in
2090 // the public API.
2091 //
2092 ///////////////////////////////////////////////////////////////////////////
2093
2094 public static void setSystemGenerated(AWTEvent e) {
2095 AWTAccessor.getAWTEventAccessor().setSystemGenerated(e);
2096 }
|