89 */
90 static void installSwingDropTargetAsNecessary(Component c,
91 TransferHandler t) {
92
93 if (!getSuppressDropTarget()) {
94 DropTarget dropHandler = c.getDropTarget();
95 if ((dropHandler == null) || (dropHandler instanceof UIResource)) {
96 if (t == null) {
97 c.setDropTarget(null);
98 } else if (!GraphicsEnvironment.isHeadless()) {
99 c.setDropTarget(new TransferHandler.SwingDropTarget(c));
100 }
101 }
102 }
103 }
104
105 /**
106 * Return true if <code>a</code> contains <code>b</code>
107 */
108 public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {
109 if (b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&
110 b.y >= a.y && (b.y + b.height) <= (a.y + a.height)) {
111 return true;
112 }
113 return false;
114 }
115
116 /**
117 * Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code>
118 */
119 public static Rectangle getLocalBounds(Component aComponent) {
120 Rectangle b = new Rectangle(aComponent.getBounds());
121 b.x = b.y = 0;
122 return b;
123 }
124
125
126 /**
127 * Returns the first <code>Window </code> ancestor of <code>c</code>, or
128 * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
129 *
130 * @param c <code>Component</code> to get <code>Window</code> ancestor
131 * of.
132 * @return the first <code>Window </code> ancestor of <code>c</code>, or
133 * {@code null} if <code>c</code> is not contained inside a
253 }
254
255 /**
256 * Returns the deepest visible descendent Component of <code>parent</code>
257 * that contains the location <code>x</code>, <code>y</code>.
258 * If <code>parent</code> does not contain the specified location,
259 * then <code>null</code> is returned. If <code>parent</code> is not a
260 * container, or none of <code>parent</code>'s visible descendents
261 * contain the specified location, <code>parent</code> is returned.
262 *
263 * @param parent the root component to begin the search
264 * @param x the x target location
265 * @param y the y target location
266 */
267 public static Component getDeepestComponentAt(Component parent, int x, int y) {
268 if (!parent.contains(x, y)) {
269 return null;
270 }
271 if (parent instanceof Container) {
272 Component components[] = ((Container)parent).getComponents();
273 for (int i = 0 ; i < components.length ; i++) {
274 Component comp = components[i];
275 if (comp != null && comp.isVisible()) {
276 Point loc = comp.getLocation();
277 if (comp instanceof Container) {
278 comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);
279 } else {
280 comp = comp.getComponentAt(x - loc.x, y - loc.y);
281 }
282 if (comp != null && comp.isVisible()) {
283 return comp;
284 }
285 }
286 }
287 }
288 return parent;
289 }
290
291
292 /**
293 * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x
294 * and y members have been converted to <code>destination</code>'s coordinate
357 sourceEvent.isPopupTrigger(),
358 MouseEvent.NOBUTTON );
359 }
360 return newEvent;
361 }
362
363
364 /**
365 * Convert a point from a component's coordinate system to
366 * screen coordinates.
367 *
368 * @param p a Point object (converted to the new coordinate system)
369 * @param c a Component object
370 */
371 public static void convertPointToScreen(Point p,Component c) {
372 Rectangle b;
373 int x,y;
374
375 do {
376 if(c instanceof JComponent) {
377 x = ((JComponent)c).getX();
378 y = ((JComponent)c).getY();
379 } else if(c instanceof java.applet.Applet ||
380 c instanceof java.awt.Window) {
381 try {
382 Point pp = c.getLocationOnScreen();
383 x = pp.x;
384 y = pp.y;
385 } catch (IllegalComponentStateException icse) {
386 x = c.getX();
387 y = c.getY();
388 }
389 } else {
390 x = c.getX();
391 y = c.getY();
392 }
393
394 p.x += x;
395 p.y += y;
396
397 if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
398 break;
399 c = c.getParent();
400 } while(c != null);
401 }
402
403 /**
404 * Convert a point from a screen coordinates to a component's
405 * coordinate system
406 *
407 * @param p a Point object (converted to the new coordinate system)
408 * @param c a Component object
409 */
410 public static void convertPointFromScreen(Point p,Component c) {
411 Rectangle b;
412 int x,y;
413
414 do {
415 if(c instanceof JComponent) {
416 x = ((JComponent)c).getX();
417 y = ((JComponent)c).getY();
418 } else if(c instanceof java.applet.Applet ||
419 c instanceof java.awt.Window) {
420 try {
421 Point pp = c.getLocationOnScreen();
422 x = pp.x;
423 y = pp.y;
424 } catch (IllegalComponentStateException icse) {
425 x = c.getX();
426 y = c.getY();
427 }
428 } else {
429 x = c.getX();
430 y = c.getY();
431 }
432
433 p.x -= x;
434 p.y -= y;
435
436 if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
437 break;
961 iconR.width = icon.getIconWidth();
962 iconR.height = icon.getIconHeight();
963 }
964 else {
965 iconR.width = iconR.height = 0;
966 }
967
968 /* Initialize the text bounds rectangle textR. If a null
969 * or and empty String was specified we substitute "" here
970 * and use 0,0,0,0 for textR.
971 */
972
973 boolean textIsEmpty = (text == null) || text.equals("");
974 int lsb = 0;
975 int rsb = 0;
976 /* Unless both text and icon are non-null, we effectively ignore
977 * the value of textIconGap.
978 */
979 int gap;
980
981 View v = null;
982 if (textIsEmpty) {
983 textR.width = textR.height = 0;
984 text = "";
985 gap = 0;
986 }
987 else {
988 int availTextWidth;
989 gap = (icon == null) ? 0 : textIconGap;
990
991 if (horizontalTextPosition == CENTER) {
992 availTextWidth = viewR.width;
993 }
994 else {
995 availTextWidth = viewR.width - (iconR.width + gap);
996 }
997 v = (c != null) ? (View) c.getClientProperty("html") : null;
998 if (v != null) {
999 textR.width = Math.min(availTextWidth,
1000 (int) v.getPreferredSpan(View.X_AXIS));
1001 textR.height = (int) v.getPreferredSpan(View.Y_AXIS);
1229 c.repaint();
1230 }
1231
1232 private static void updateComponentTreeUI0(Component c) {
1233 if (c instanceof JComponent) {
1234 JComponent jc = (JComponent) c;
1235 jc.updateUI();
1236 JPopupMenu jpm =jc.getComponentPopupMenu();
1237 if(jpm != null) {
1238 updateComponentTreeUI(jpm);
1239 }
1240 }
1241 Component[] children = null;
1242 if (c instanceof JMenu) {
1243 children = ((JMenu)c).getMenuComponents();
1244 }
1245 else if (c instanceof Container) {
1246 children = ((Container)c).getComponents();
1247 }
1248 if (children != null) {
1249 for(int i = 0; i < children.length; i++) {
1250 updateComponentTreeUI0(children[i]);
1251 }
1252 }
1253 }
1254
1255
1256 /**
1257 * Causes <i>doRun.run()</i> to be executed asynchronously on the
1258 * AWT event dispatching thread. This will happen after all
1259 * pending AWT events have been processed. This method should
1260 * be used when an application thread needs to update the GUI.
1261 * In the following example the <code>invokeLater</code> call queues
1262 * the <code>Runnable</code> object <code>doHelloWorld</code>
1263 * on the event dispatching thread and
1264 * then prints a message.
1265 * <pre>
1266 * Runnable doHelloWorld = new Runnable() {
1267 * public void run() {
1268 * System.out.println("Hello World on " + Thread.currentThread());
1269 * }
1270 * };
1574 event, pressed);
1575 }
1576 if ((component instanceof Applet) ||
1577 (component instanceof Window)) {
1578 // No JComponents, if Window or Applet parent, process
1579 // WHEN_IN_FOCUSED_WINDOW bindings.
1580 return JComponent.processKeyBindingsForAllComponents(
1581 event, (Container)component, pressed);
1582 }
1583 component = component.getParent();
1584 }
1585 }
1586 return false;
1587 }
1588
1589 /**
1590 * Returns true if the <code>e</code> is a valid KeyEvent to use in
1591 * processing the key bindings associated with JComponents.
1592 */
1593 static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
1594 if (e.getID() == KeyEvent.KEY_TYPED) {
1595 int mod = e.getModifiers();
1596 if (((mod & ActionEvent.ALT_MASK) != 0) &&
1597 ((mod & ActionEvent.CTRL_MASK) == 0)) {
1598 // filter out typed "alt-?" keys, but not those created
1599 // with AltGr, and not control characters
1600 return false;
1601 }
1602 }
1603 return true;
1604 }
1605
1606 /**
1607 * Invokes <code>actionPerformed</code> on <code>action</code> if
1608 * <code>action</code> is enabled (and non-{@code null}). The command for the
1609 * ActionEvent is determined by:
1610 * <ol>
1611 * <li>If the action was registered via
1612 * <code>registerKeyboardAction</code>, then the command string
1613 * passed in ({@code null} will be used if {@code null} was passed in).
1614 * <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}.
1615 * <li>String value of the KeyEvent, unless <code>getKeyChar</code>
1616 * returns KeyEvent.CHAR_UNDEFINED..
1617 * </ol>
1618 * This will return true if <code>action</code> is non-{@code null} and
1619 * actionPerformed is invoked on it.
1620 *
1621 * @since 1.3
1622 */
1683 while (map != null) {
1684 InputMap parent = map.getParent();
1685 if (parent == null || (parent instanceof UIResource)) {
1686 map.setParent(uiInputMap);
1687 return;
1688 }
1689 map = parent;
1690 }
1691 }
1692
1693
1694 /**
1695 * Convenience method to change the UI ActionMap for <code>component</code>
1696 * to <code>uiActionMap</code>. If <code>uiActionMap</code> is {@code null},
1697 * this removes any previously installed UI ActionMap.
1698 *
1699 * @since 1.3
1700 */
1701 public static void replaceUIActionMap(JComponent component,
1702 ActionMap uiActionMap) {
1703 ActionMap map = component.getActionMap((uiActionMap != null));;
1704
1705 while (map != null) {
1706 ActionMap parent = map.getParent();
1707 if (parent == null || (parent instanceof UIResource)) {
1708 map.setParent(uiActionMap);
1709 return;
1710 }
1711 map = parent;
1712 }
1713 }
1714
1715
1716 /**
1717 * Returns the InputMap provided by the UI for condition
1718 * <code>condition</code> in component <code>component</code>.
1719 * <p>This will return {@code null} if the UI has not installed a InputMap
1720 * of the specified type.
1721 *
1722 * @since 1.3
1723 */
1750 map = parent;
1751 }
1752 return null;
1753 }
1754
1755
1756 // Don't use String, as it's not guaranteed to be unique in a Hashtable.
1757 private static final Object sharedOwnerFrameKey = new Object(); // SwingUtilities.sharedOwnerFrame
1758
1759 static class SharedOwnerFrame extends Frame implements WindowListener {
1760 public void addNotify() {
1761 super.addNotify();
1762 installListeners();
1763 }
1764
1765 /**
1766 * Install window listeners on owned windows to watch for displayability changes
1767 */
1768 void installListeners() {
1769 Window[] windows = getOwnedWindows();
1770 for (int ind = 0; ind < windows.length; ind++){
1771 Window window = windows[ind];
1772 if (window != null) {
1773 window.removeWindowListener(this);
1774 window.addWindowListener(this);
1775 }
1776 }
1777 }
1778
1779 /**
1780 * Watches for displayability changes and disposes shared instance if there are no
1781 * displayable children left.
1782 */
1783 public void windowClosed(WindowEvent e) {
1784 synchronized(getTreeLock()) {
1785 Window[] windows = getOwnedWindows();
1786 for (int ind = 0; ind < windows.length; ind++) {
1787 Window window = windows[ind];
1788 if (window != null) {
1789 if (window.isDisplayable()) {
1790 return;
1791 }
1792 window.removeWindowListener(this);
1793 }
1794 }
1795 dispose();
1796 }
1797 }
1798 public void windowOpened(WindowEvent e) {
1799 }
1800 public void windowClosing(WindowEvent e) {
1801 }
1802 public void windowIconified(WindowEvent e) {
1803 }
1804 public void windowDeiconified(WindowEvent e) {
1805 }
1806 public void windowActivated(WindowEvent e) {
1807 }
1855 /* Don't make these AppContext accessors public or protected --
1856 * since AppContext is in sun.awt in 1.2, we shouldn't expose it
1857 * even indirectly with a public API.
1858 */
1859 // REMIND(aim): phase out use of 4 methods below since they
1860 // are just private covers for AWT methods (?)
1861
1862 static Object appContextGet(Object key) {
1863 return AppContext.getAppContext().get(key);
1864 }
1865
1866 static void appContextPut(Object key, Object value) {
1867 AppContext.getAppContext().put(key, value);
1868 }
1869
1870 static void appContextRemove(Object key) {
1871 AppContext.getAppContext().remove(key);
1872 }
1873
1874
1875 static Class loadSystemClass(String className) throws ClassNotFoundException {
1876 ReflectUtil.checkPackageAccess(className);
1877 return Class.forName(className, true, Thread.currentThread().
1878 getContextClassLoader());
1879 }
1880
1881
1882 /*
1883 * Convenience function for determining ComponentOrientation. Helps us
1884 * avoid having Munge directives throughout the code.
1885 */
1886 static boolean isLeftToRight( Component c ) {
1887 return c.getComponentOrientation().isLeftToRight();
1888 }
1889 private SwingUtilities() {
1890 throw new Error("SwingUtilities is just a container for static methods");
1891 }
1892
1893 /**
1894 * Returns true if the Icon <code>icon</code> is an instance of
1895 * ImageIcon, and the image it contains is the same as <code>image</code>.
|
89 */
90 static void installSwingDropTargetAsNecessary(Component c,
91 TransferHandler t) {
92
93 if (!getSuppressDropTarget()) {
94 DropTarget dropHandler = c.getDropTarget();
95 if ((dropHandler == null) || (dropHandler instanceof UIResource)) {
96 if (t == null) {
97 c.setDropTarget(null);
98 } else if (!GraphicsEnvironment.isHeadless()) {
99 c.setDropTarget(new TransferHandler.SwingDropTarget(c));
100 }
101 }
102 }
103 }
104
105 /**
106 * Return true if <code>a</code> contains <code>b</code>
107 */
108 public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {
109 return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&
110 b.y >= a.y && (b.y + b.height) <= (a.y + a.height);
111 }
112
113 /**
114 * Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code>
115 */
116 public static Rectangle getLocalBounds(Component aComponent) {
117 Rectangle b = new Rectangle(aComponent.getBounds());
118 b.x = b.y = 0;
119 return b;
120 }
121
122
123 /**
124 * Returns the first <code>Window </code> ancestor of <code>c</code>, or
125 * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
126 *
127 * @param c <code>Component</code> to get <code>Window</code> ancestor
128 * of.
129 * @return the first <code>Window </code> ancestor of <code>c</code>, or
130 * {@code null} if <code>c</code> is not contained inside a
250 }
251
252 /**
253 * Returns the deepest visible descendent Component of <code>parent</code>
254 * that contains the location <code>x</code>, <code>y</code>.
255 * If <code>parent</code> does not contain the specified location,
256 * then <code>null</code> is returned. If <code>parent</code> is not a
257 * container, or none of <code>parent</code>'s visible descendents
258 * contain the specified location, <code>parent</code> is returned.
259 *
260 * @param parent the root component to begin the search
261 * @param x the x target location
262 * @param y the y target location
263 */
264 public static Component getDeepestComponentAt(Component parent, int x, int y) {
265 if (!parent.contains(x, y)) {
266 return null;
267 }
268 if (parent instanceof Container) {
269 Component components[] = ((Container)parent).getComponents();
270 for (Component comp : components) {
271 if (comp != null && comp.isVisible()) {
272 Point loc = comp.getLocation();
273 if (comp instanceof Container) {
274 comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);
275 } else {
276 comp = comp.getComponentAt(x - loc.x, y - loc.y);
277 }
278 if (comp != null && comp.isVisible()) {
279 return comp;
280 }
281 }
282 }
283 }
284 return parent;
285 }
286
287
288 /**
289 * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x
290 * and y members have been converted to <code>destination</code>'s coordinate
353 sourceEvent.isPopupTrigger(),
354 MouseEvent.NOBUTTON );
355 }
356 return newEvent;
357 }
358
359
360 /**
361 * Convert a point from a component's coordinate system to
362 * screen coordinates.
363 *
364 * @param p a Point object (converted to the new coordinate system)
365 * @param c a Component object
366 */
367 public static void convertPointToScreen(Point p,Component c) {
368 Rectangle b;
369 int x,y;
370
371 do {
372 if(c instanceof JComponent) {
373 x = c.getX();
374 y = c.getY();
375 } else if(c instanceof java.applet.Applet ||
376 c instanceof java.awt.Window) {
377 try {
378 Point pp = c.getLocationOnScreen();
379 x = pp.x;
380 y = pp.y;
381 } catch (IllegalComponentStateException icse) {
382 x = c.getX();
383 y = c.getY();
384 }
385 } else {
386 x = c.getX();
387 y = c.getY();
388 }
389
390 p.x += x;
391 p.y += y;
392
393 if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
394 break;
395 c = c.getParent();
396 } while(c != null);
397 }
398
399 /**
400 * Convert a point from a screen coordinates to a component's
401 * coordinate system
402 *
403 * @param p a Point object (converted to the new coordinate system)
404 * @param c a Component object
405 */
406 public static void convertPointFromScreen(Point p,Component c) {
407 Rectangle b;
408 int x,y;
409
410 do {
411 if(c instanceof JComponent) {
412 x = c.getX();
413 y = c.getY();
414 } else if(c instanceof java.applet.Applet ||
415 c instanceof java.awt.Window) {
416 try {
417 Point pp = c.getLocationOnScreen();
418 x = pp.x;
419 y = pp.y;
420 } catch (IllegalComponentStateException icse) {
421 x = c.getX();
422 y = c.getY();
423 }
424 } else {
425 x = c.getX();
426 y = c.getY();
427 }
428
429 p.x -= x;
430 p.y -= y;
431
432 if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
433 break;
957 iconR.width = icon.getIconWidth();
958 iconR.height = icon.getIconHeight();
959 }
960 else {
961 iconR.width = iconR.height = 0;
962 }
963
964 /* Initialize the text bounds rectangle textR. If a null
965 * or and empty String was specified we substitute "" here
966 * and use 0,0,0,0 for textR.
967 */
968
969 boolean textIsEmpty = (text == null) || text.equals("");
970 int lsb = 0;
971 int rsb = 0;
972 /* Unless both text and icon are non-null, we effectively ignore
973 * the value of textIconGap.
974 */
975 int gap;
976
977 View v;
978 if (textIsEmpty) {
979 textR.width = textR.height = 0;
980 text = "";
981 gap = 0;
982 }
983 else {
984 int availTextWidth;
985 gap = (icon == null) ? 0 : textIconGap;
986
987 if (horizontalTextPosition == CENTER) {
988 availTextWidth = viewR.width;
989 }
990 else {
991 availTextWidth = viewR.width - (iconR.width + gap);
992 }
993 v = (c != null) ? (View) c.getClientProperty("html") : null;
994 if (v != null) {
995 textR.width = Math.min(availTextWidth,
996 (int) v.getPreferredSpan(View.X_AXIS));
997 textR.height = (int) v.getPreferredSpan(View.Y_AXIS);
1225 c.repaint();
1226 }
1227
1228 private static void updateComponentTreeUI0(Component c) {
1229 if (c instanceof JComponent) {
1230 JComponent jc = (JComponent) c;
1231 jc.updateUI();
1232 JPopupMenu jpm =jc.getComponentPopupMenu();
1233 if(jpm != null) {
1234 updateComponentTreeUI(jpm);
1235 }
1236 }
1237 Component[] children = null;
1238 if (c instanceof JMenu) {
1239 children = ((JMenu)c).getMenuComponents();
1240 }
1241 else if (c instanceof Container) {
1242 children = ((Container)c).getComponents();
1243 }
1244 if (children != null) {
1245 for (Component child : children) {
1246 updateComponentTreeUI0(child);
1247 }
1248 }
1249 }
1250
1251
1252 /**
1253 * Causes <i>doRun.run()</i> to be executed asynchronously on the
1254 * AWT event dispatching thread. This will happen after all
1255 * pending AWT events have been processed. This method should
1256 * be used when an application thread needs to update the GUI.
1257 * In the following example the <code>invokeLater</code> call queues
1258 * the <code>Runnable</code> object <code>doHelloWorld</code>
1259 * on the event dispatching thread and
1260 * then prints a message.
1261 * <pre>
1262 * Runnable doHelloWorld = new Runnable() {
1263 * public void run() {
1264 * System.out.println("Hello World on " + Thread.currentThread());
1265 * }
1266 * };
1570 event, pressed);
1571 }
1572 if ((component instanceof Applet) ||
1573 (component instanceof Window)) {
1574 // No JComponents, if Window or Applet parent, process
1575 // WHEN_IN_FOCUSED_WINDOW bindings.
1576 return JComponent.processKeyBindingsForAllComponents(
1577 event, (Container)component, pressed);
1578 }
1579 component = component.getParent();
1580 }
1581 }
1582 return false;
1583 }
1584
1585 /**
1586 * Returns true if the <code>e</code> is a valid KeyEvent to use in
1587 * processing the key bindings associated with JComponents.
1588 */
1589 static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
1590 return true;
1591 }
1592
1593 /**
1594 * Invokes <code>actionPerformed</code> on <code>action</code> if
1595 * <code>action</code> is enabled (and non-{@code null}). The command for the
1596 * ActionEvent is determined by:
1597 * <ol>
1598 * <li>If the action was registered via
1599 * <code>registerKeyboardAction</code>, then the command string
1600 * passed in ({@code null} will be used if {@code null} was passed in).
1601 * <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}.
1602 * <li>String value of the KeyEvent, unless <code>getKeyChar</code>
1603 * returns KeyEvent.CHAR_UNDEFINED..
1604 * </ol>
1605 * This will return true if <code>action</code> is non-{@code null} and
1606 * actionPerformed is invoked on it.
1607 *
1608 * @since 1.3
1609 */
1670 while (map != null) {
1671 InputMap parent = map.getParent();
1672 if (parent == null || (parent instanceof UIResource)) {
1673 map.setParent(uiInputMap);
1674 return;
1675 }
1676 map = parent;
1677 }
1678 }
1679
1680
1681 /**
1682 * Convenience method to change the UI ActionMap for <code>component</code>
1683 * to <code>uiActionMap</code>. If <code>uiActionMap</code> is {@code null},
1684 * this removes any previously installed UI ActionMap.
1685 *
1686 * @since 1.3
1687 */
1688 public static void replaceUIActionMap(JComponent component,
1689 ActionMap uiActionMap) {
1690 ActionMap map = component.getActionMap((uiActionMap != null));
1691
1692 while (map != null) {
1693 ActionMap parent = map.getParent();
1694 if (parent == null || (parent instanceof UIResource)) {
1695 map.setParent(uiActionMap);
1696 return;
1697 }
1698 map = parent;
1699 }
1700 }
1701
1702
1703 /**
1704 * Returns the InputMap provided by the UI for condition
1705 * <code>condition</code> in component <code>component</code>.
1706 * <p>This will return {@code null} if the UI has not installed a InputMap
1707 * of the specified type.
1708 *
1709 * @since 1.3
1710 */
1737 map = parent;
1738 }
1739 return null;
1740 }
1741
1742
1743 // Don't use String, as it's not guaranteed to be unique in a Hashtable.
1744 private static final Object sharedOwnerFrameKey = new Object(); // SwingUtilities.sharedOwnerFrame
1745
1746 static class SharedOwnerFrame extends Frame implements WindowListener {
1747 public void addNotify() {
1748 super.addNotify();
1749 installListeners();
1750 }
1751
1752 /**
1753 * Install window listeners on owned windows to watch for displayability changes
1754 */
1755 void installListeners() {
1756 Window[] windows = getOwnedWindows();
1757 for (Window window : windows) {
1758 if (window != null) {
1759 window.removeWindowListener(this);
1760 window.addWindowListener(this);
1761 }
1762 }
1763 }
1764
1765 /**
1766 * Watches for displayability changes and disposes shared instance if there are no
1767 * displayable children left.
1768 */
1769 public void windowClosed(WindowEvent e) {
1770 synchronized(getTreeLock()) {
1771 Window[] windows = getOwnedWindows();
1772 for (Window window : windows) {
1773 if (window != null) {
1774 if (window.isDisplayable()) {
1775 return;
1776 }
1777 window.removeWindowListener(this);
1778 }
1779 }
1780 dispose();
1781 }
1782 }
1783 public void windowOpened(WindowEvent e) {
1784 }
1785 public void windowClosing(WindowEvent e) {
1786 }
1787 public void windowIconified(WindowEvent e) {
1788 }
1789 public void windowDeiconified(WindowEvent e) {
1790 }
1791 public void windowActivated(WindowEvent e) {
1792 }
1840 /* Don't make these AppContext accessors public or protected --
1841 * since AppContext is in sun.awt in 1.2, we shouldn't expose it
1842 * even indirectly with a public API.
1843 */
1844 // REMIND(aim): phase out use of 4 methods below since they
1845 // are just private covers for AWT methods (?)
1846
1847 static Object appContextGet(Object key) {
1848 return AppContext.getAppContext().get(key);
1849 }
1850
1851 static void appContextPut(Object key, Object value) {
1852 AppContext.getAppContext().put(key, value);
1853 }
1854
1855 static void appContextRemove(Object key) {
1856 AppContext.getAppContext().remove(key);
1857 }
1858
1859
1860 static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
1861 ReflectUtil.checkPackageAccess(className);
1862 return Class.forName(className, true, Thread.currentThread().
1863 getContextClassLoader());
1864 }
1865
1866
1867 /*
1868 * Convenience function for determining ComponentOrientation. Helps us
1869 * avoid having Munge directives throughout the code.
1870 */
1871 static boolean isLeftToRight( Component c ) {
1872 return c.getComponentOrientation().isLeftToRight();
1873 }
1874 private SwingUtilities() {
1875 throw new Error("SwingUtilities is just a container for static methods");
1876 }
1877
1878 /**
1879 * Returns true if the Icon <code>icon</code> is an instance of
1880 * ImageIcon, and the image it contains is the same as <code>image</code>.
|