1. /*
  2. * @(#)Window.java 1.137 01/02/09
  3. *
  4. * Copyright 1995-2001 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.awt;
  11. import java.awt.peer.WindowPeer;
  12. import java.awt.event.*;
  13. import java.util.Vector;
  14. import java.util.Locale;
  15. import java.util.EventListener;
  16. import java.io.Serializable;
  17. import java.io.ObjectOutputStream;
  18. import java.io.ObjectInputStream;
  19. import java.io.IOException;
  20. import java.io.OptionalDataException;
  21. import java.awt.im.InputContext;
  22. import java.util.ResourceBundle;
  23. import java.lang.ref.WeakReference;
  24. import java.lang.reflect.InvocationTargetException;
  25. import java.security.AccessController;
  26. import javax.accessibility.*;
  27. import sun.security.action.GetPropertyAction;
  28. import sun.awt.DebugHelper;
  29. /**
  30. * A <code>Window</code> object is a top-level window with no borders and no
  31. * menubar.
  32. * The default layout for a window is <code>BorderLayout</code>.
  33. * <p>
  34. * A window must have either a frame, dialog, or another window defined as its
  35. * owner when it's constructed.
  36. * <p>
  37. * In a multi-screen environment, you can create a <code>Window</code>
  38. * on a different screen device by constructing the <code>Window</code>
  39. * with {@link Window(Window, GraphicsConfiguration)}. The
  40. * <code>GraphicsConfiguration</code> object is one of the
  41. * <code>GraphicsConfiguration</code> objects of the target screen device.
  42. * <p>
  43. * In a virtual device multi-screen environment in which the desktop
  44. * area could span multiple physical screen devices, the bounds of all
  45. * configurations are relative to the virtual device coordinate system.
  46. * The origin of the virtual-coordinate system is at the upper left-hand
  47. * corner of the primary physical screen. Depending on the location of
  48. * the primary screen in the virtual device, negative coordinates are
  49. * possible, as shown in the following figure.
  50. * <p>
  51. * <img src="doc-files/MultiScreen.gif"
  52. * ALIGN=center HSPACE=10 VSPACE=7>
  53. * <p>
  54. * In such an environment, when calling <code>setLocation</code>,
  55. * you must pass a virtual coordinate to this method. Similarly,
  56. * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns
  57. * virtual device coordinates. Call the <code>getBounds</code> method
  58. * of a <code>GraphicsConfiguration</code> to find its origin in the virtual
  59. * coordinate system.
  60. * <p>
  61. * The following code sets the location of a <code>Window</code>
  62. * at (10, 10) relative to the origin of the physical screen
  63. * of the corresponding <code>GraphicsConfiguration</code>. If the
  64. * bounds of the <code>GraphicsConfiguration</code> is not taken
  65. * into account, the <code>Window</code> location would be set
  66. * at (10, 10) relative to the virtual-coordinate system and would appear
  67. * on the primary physical screen, which might be different from the
  68. * physical screen of the specified <code>GraphicsConfiguration</code>.
  69. *
  70. * <pre>
  71. * Window w = new Window(Window owner, GraphicsConfiguration gc);
  72. * Rectangle bounds = gc.getBounds();
  73. * w.setLocation(10 + bounds.x, 10 + bounds.y);
  74. * </pre>
  75. *
  76. * <p>
  77. * Windows are capable of generating the following window events:
  78. * WindowOpened, WindowClosed.
  79. *
  80. * @version 1.137, 02/09/01
  81. * @author Sami Shaio
  82. * @author Arthur van Hoff
  83. * @see WindowEvent
  84. * @see #addWindowListener
  85. * @see java.awt.BorderLayout
  86. * @since JDK1.0
  87. */
  88. public class Window extends Container implements Accessible {
  89. /**
  90. * This represents the warning message that is
  91. * to be displayed in a non secure window. ie :
  92. * a window that has a security manager installed for
  93. * which calling SecurityManager.checkTopLevelWindow()
  94. * is false. This message can be displayed anywhere in
  95. * the window.
  96. *
  97. * @serial
  98. * @see getWarningString()
  99. */
  100. String warningString;
  101. static final int OPENED = 0x01;
  102. /**
  103. * An Integer value representing the Window State.
  104. *
  105. * @serial
  106. * @since 1.2
  107. * @see show()
  108. */
  109. int state;
  110. /**
  111. * A vector containing all the windows this
  112. * window currently owns.
  113. * @since 1.2
  114. * @see getOwnedWindows()
  115. */
  116. transient Vector ownedWindowList = new Vector();
  117. private transient WeakReference weakThis;
  118. transient WindowListener windowListener;
  119. private transient boolean active = false; // == true when Window receives WINDOW_ACTIVATED event
  120. // == false when Window receives WINDOW_DEACTIVATED event
  121. transient InputContext inputContext;
  122. private transient Object inputContextLock = new Object();
  123. /**
  124. * The Focus for the Window in question, and its components.
  125. *
  126. * @serial
  127. * @since 1.2
  128. * @See java.awt.FocusManager
  129. */
  130. private FocusManager focusMgr;
  131. private static final String base = "win";
  132. private static int nameCounter = 0;
  133. /*
  134. * JDK 1.1 serialVersionUID
  135. */
  136. private static final long serialVersionUID = 4497834738069338734L;
  137. private static final DebugHelper dbg = DebugHelper.create(Container.class);
  138. static {
  139. /* ensure that the necessary native libraries are loaded */
  140. Toolkit.loadLibraries();
  141. initIDs();
  142. }
  143. /**
  144. * Initialize JNI field and method IDs for fields that may be
  145. accessed from C.
  146. */
  147. private static native void initIDs();
  148. /**
  149. * Constructs a new window in default size with the
  150. * specified <code>GraphicsConfiguration</code>.
  151. * <p>
  152. * If there is a security manager, this method first calls
  153. * the security manager's <code>checkTopLevelWindow</code>
  154. * method with <code>this</code>
  155. * as its argument to determine whether or not the window
  156. * must be displayed with a warning banner.
  157. * @param gc the <code>GraphicsConfiguration</code>
  158. * of the target screen device. If <code>gc</code> is
  159. * <code>null</code>, the system default
  160. * <code>GraphicsConfiguration</code> is assumed.
  161. * @exception IllegalArgumentException if <code>gc</code>
  162. * is not from a screen device.
  163. * @see java.lang.SecurityManager#checkTopLevelWindow
  164. */
  165. Window(GraphicsConfiguration gc) {
  166. setWarningString();
  167. this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  168. this.focusMgr = new FocusManager(this);
  169. this.visible = false;
  170. if (gc == null) {
  171. this.graphicsConfig =
  172. GraphicsEnvironment.getLocalGraphicsEnvironment().
  173. getDefaultScreenDevice().getDefaultConfiguration();
  174. } else {
  175. this.graphicsConfig = gc;
  176. }
  177. if (graphicsConfig.getDevice().getType() !=
  178. GraphicsDevice.TYPE_RASTER_SCREEN) {
  179. throw new IllegalArgumentException("not a screen device");
  180. }
  181. setLayout(new BorderLayout());
  182. /* offset the initial location with the original of the screen */
  183. Rectangle screenBounds = graphicsConfig.getBounds();
  184. int x = getX() + screenBounds.x;
  185. int y = getY() + screenBounds.y;
  186. setLocation(x, y);
  187. }
  188. /**
  189. * Constructs a new window in the default size.
  190. *
  191. * <p>First, if there is a security manager, its
  192. * <code>checkTopLevelWindow</code>
  193. * method is called with <code>this</code>
  194. * as its argument
  195. * to see if it's ok to display the window without a warning banner.
  196. * If the default implementation of <code>checkTopLevelWindow</code>
  197. * is used (that is, that method is not overriden), then this results in
  198. * a call to the security manager's <code>checkPermission</code> method with an
  199. * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
  200. * permission. It that method raises a SecurityException,
  201. * <code>checkTopLevelWindow</code> returns false, otherwise it
  202. * returns true. If it returns false, a warning banner is created.
  203. *
  204. * @see java.lang.SecurityManager#checkTopLevelWindow
  205. */
  206. Window() {
  207. this((GraphicsConfiguration)null);
  208. }
  209. /**
  210. * Constructs a new invisible window with the specified
  211. * Frame as its owner.
  212. * <p>
  213. * If there is a security manager, this method first calls
  214. * the security manager's <code>checkTopLevelWindow</code>
  215. * method with <code>this</code>
  216. * as its argument to determine whether or not the window
  217. * must be displayed with a warning banner.
  218. *
  219. * @param owner the <code>Frame</code> to act as owner
  220. * @exception IllegalArgumentException if <code>gc</code>
  221. * is not from a screen device.
  222. * @exception java.lang.IllegalArgumentException if
  223. * <code>owner</code> is <code>null</code>
  224. * @see java.lang.SecurityManager#checkTopLevelWindow
  225. */
  226. public Window(Frame owner) {
  227. this(owner == null ? (GraphicsConfiguration)null :
  228. owner.getGraphicsConfiguration());
  229. ownedInit(owner);
  230. }
  231. /**
  232. * Constructs a new invisible window with the specified
  233. * Window as its owner.
  234. * <p>
  235. * If there is a security manager, this method first calls
  236. * the security manager's <code>checkTopLevelWindow</code>
  237. * method with <code>this</code>
  238. * as its argument to determine whether or not the window
  239. * must be displayed with a warning banner.
  240. *
  241. * @param owner the Window to act as owner
  242. * @exception java.lang.IllegalArgumentException if <code>owner</code>
  243. * is <code>null</code>
  244. * @see java.lang.SecurityManager#checkTopLevelWindow
  245. * @since 1.2
  246. */
  247. public Window(Window owner) {
  248. this(owner == null ? (GraphicsConfiguration)null :
  249. owner.getGraphicsConfiguration());
  250. ownedInit(owner);
  251. }
  252. /**
  253. * Constructs a new invisible window with the specified
  254. * window as its owner and a
  255. * <code>GraphicsConfiguration</code> of a screen device.
  256. * <p>
  257. * If there is a security manager, this method first calls
  258. * the security manager's <code>checkTopLevelWindow</code>
  259. * method with <code>this</code>
  260. * as its argument to determine whether or not the window
  261. * must be displayed with a warning banner.
  262. * @param owner the window to act as owner
  263. * @param gc the <code>GraphicsConfiguration</code>
  264. * of the target screen device. If <code>gc</code> is
  265. * <code>null</code>, the system default
  266. * <code>GraphicsConfiguration</code> is assumed.
  267. * @throws IllegalArgumentException if
  268. * <code>owner</code> is <code>null</code>.
  269. * @throws IllegalArgumentException if <code>gc</code> is not from
  270. * a screen device.
  271. * @see java.lang.SecurityManager#checkTopLevelWindow
  272. * @see java.awt.GraphicsConfiguration#getBounds
  273. * @since 1.3
  274. */
  275. public Window(Window owner, GraphicsConfiguration gc) {
  276. this(gc);
  277. ownedInit(owner);
  278. }
  279. private void ownedInit(Window owner) {
  280. if (owner == null) {
  281. throw new IllegalArgumentException("null owner window");
  282. }
  283. this.parent = owner;
  284. this.weakThis = new WeakReference(this);
  285. owner.addOwnedWindow(weakThis);
  286. }
  287. /**
  288. * Disposes of the input methods and context, and removes the WeakReference
  289. * which formerly pointed to this Window from the parent's owned Window
  290. * list.
  291. */
  292. protected void finalize() throws Throwable {
  293. if (parent != null) {
  294. ((Window)parent).removeOwnedWindow(weakThis);
  295. }
  296. super.finalize();
  297. }
  298. /**
  299. * Construct a name for this component. Called by getName() when the
  300. * name is null.
  301. */
  302. String constructComponentName() {
  303. synchronized (getClass()) {
  304. return base + nameCounter++;
  305. }
  306. }
  307. /**
  308. * Makes this Window displayable by creating the connection to its
  309. * native screen resource.
  310. * This method is called internally by the toolkit and should
  311. * not be called directly by programs.
  312. * @see Component#isDisplayable
  313. * @see Container#removeNotify
  314. * @since JDK1.0
  315. */
  316. public void addNotify() {
  317. synchronized (getTreeLock()) {
  318. Container parent = this.parent;
  319. if (parent != null && parent.getPeer() == null) {
  320. parent.addNotify();
  321. }
  322. if (peer == null)
  323. peer = getToolkit().createWindow(this);
  324. super.addNotify();
  325. }
  326. }
  327. /**
  328. * Causes this Window to be sized to fit the preferred size
  329. * and layouts of its subcomponents. If the window and/or its owner
  330. * are not yet displayable, both are made displayable before
  331. * calculating the preferred size. The Window will be validated
  332. * after the preferredSize is calculated.
  333. * @see Component#isDisplayable
  334. */
  335. public void pack() {
  336. Container parent = this.parent;
  337. if (parent != null && parent.getPeer() == null) {
  338. parent.addNotify();
  339. }
  340. if (peer == null) {
  341. addNotify();
  342. }
  343. setSize(getPreferredSize());
  344. isPacked = true;
  345. validate();
  346. }
  347. /**
  348. * Makes the Window visible. If the Window and/or its owner
  349. * are not yet displayable, both are made displayable. The
  350. * Window will be validated prior to being made visible.
  351. * If the Window is already visible, this will bring the Window
  352. * to the front.
  353. * @see java.awt.Component#isDisplayable
  354. * @see java.awt.Window#toFront
  355. * @see java.awt.Component#setVisible
  356. */
  357. public void show() {
  358. if (peer == null) {
  359. addNotify();
  360. }
  361. validate();
  362. if (visible) {
  363. toFront();
  364. } else {
  365. super.show();
  366. }
  367. // If first time shown, generate WindowOpened event
  368. if ((state & OPENED) == 0) {
  369. postWindowEvent(WindowEvent.WINDOW_OPENED);
  370. state |= OPENED;
  371. }
  372. }
  373. synchronized void postWindowEvent(int id) {
  374. // Fix for 4253157: accessibility adds AWTEventListener to
  375. // Toolkit to look for WINDOW_OPENED events, so post them
  376. // unconditionally for now.
  377. // if (windowListener != null
  378. // || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) {
  379. WindowEvent e = new WindowEvent(this, id);
  380. Toolkit.getEventQueue().postEvent(e);
  381. // }
  382. }
  383. /**
  384. * Hide this Window, its subcomponents, and all of its owned children.
  385. * The Window and its subcomponents can be made visible again
  386. * with a call to <code>show</code>.
  387. * </p>
  388. * @see Window#show
  389. * @see Window#dispose
  390. */
  391. public void hide() {
  392. synchronized(ownedWindowList) {
  393. for (int i = 0; i < ownedWindowList.size(); i++) {
  394. Window child = (Window) (((WeakReference)
  395. (ownedWindowList.elementAt(i))).get());
  396. if (child != null) {
  397. child.hide();
  398. }
  399. }
  400. }
  401. super.hide();
  402. }
  403. /**
  404. * Releases all of the native screen resources used by this Window,
  405. * its subcomponents, and all of its owned children. That is, the
  406. * resources for these Components will be destroyed, any memory
  407. * they consume will be returned to the OS, and they will be marked
  408. * as undisplayable.
  409. * <p>
  410. * The Window and its subcomponents can be made displayable again
  411. * by rebuilding the native resources with a subsequent call to
  412. * <code>pack</code> or <code>show</code>. The states of the recreated
  413. * Window and its subcomponents will be identical to the states of these
  414. * objects at the point where the Window was disposed (not accounting for
  415. * additional modifcations between those actions).
  416. * </p>
  417. * @see Component#isDisplayable
  418. * @see Window#pack
  419. * @see Window#show
  420. */
  421. public void dispose() {
  422. class DisposeAction implements Runnable {
  423. public void run() {
  424. synchronized(ownedWindowList) {
  425. for (int i = 0; i < ownedWindowList.size(); i++) {
  426. Window child = (Window) (((WeakReference)
  427. (ownedWindowList.elementAt(i))).get());
  428. if (child != null) {
  429. child.dispose();
  430. }
  431. }
  432. }
  433. hide();
  434. removeNotify();
  435. synchronized (inputContextLock) {
  436. if (inputContext != null) {
  437. inputContext.dispose();
  438. inputContext = null;
  439. }
  440. }
  441. }
  442. }
  443. DisposeAction action = new DisposeAction();
  444. if (EventQueue.isDispatchThread()) {
  445. action.run();
  446. }
  447. else {
  448. try {
  449. EventQueue.invokeAndWait(action);
  450. }
  451. catch (InterruptedException e) {
  452. System.err.println("Disposal was interrupted:");
  453. e.printStackTrace();
  454. }
  455. catch (InvocationTargetException e) {
  456. System.err.println("Exception during disposal:");
  457. e.printStackTrace();
  458. }
  459. }
  460. // Execute outside the Runnable because postWindowEvent is
  461. // synchronized on (this). We don't need to synchronize the call
  462. // on the EventQueue anyways.
  463. postWindowEvent(WindowEvent.WINDOW_CLOSED);
  464. }
  465. // Should only be called while holding tree lock
  466. void adjustListeningChildren(long mask, int num) {
  467. if (dbg.on) {
  468. dbg.assert(mask == AWTEvent.HIERARCHY_EVENT_MASK ||
  469. mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK ||
  470. mask == (AWTEvent.HIERARCHY_EVENT_MASK |
  471. AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
  472. }
  473. if (num == 0)
  474. return;
  475. if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
  476. listeningChildren += num;
  477. }
  478. if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
  479. listeningBoundsChildren += num;
  480. }
  481. }
  482. /**
  483. * Brings this window to the front.
  484. * Places this window at the top of the stacking order and
  485. * shows it in front of any other windows.
  486. * @see java.awt.Window#toBack
  487. */
  488. public void toFront() {
  489. WindowPeer peer = (WindowPeer)this.peer;
  490. if (peer != null) {
  491. peer.toFront();
  492. }
  493. }
  494. /**
  495. * Sends this window to the back.
  496. * Places this window at the bottom of the stacking order and
  497. * makes the corresponding adjustment to other visible windows.
  498. * @see java.awt.Window#toFront
  499. */
  500. public void toBack() {
  501. WindowPeer peer = (WindowPeer)this.peer;
  502. if (peer != null) {
  503. peer.toBack();
  504. }
  505. }
  506. /**
  507. * Returns the toolkit of this frame.
  508. * @return the toolkit of this window.
  509. * @see java.awt.Toolkit
  510. * @see java.awt.Toolkit#getDefaultToolkit()
  511. * @see java.awt.Component#getToolkit()
  512. */
  513. public Toolkit getToolkit() {
  514. return Toolkit.getDefaultToolkit();
  515. }
  516. /**
  517. * Gets the warning string that is displayed with this window.
  518. * If this window is insecure, the warning string is displayed
  519. * somewhere in the visible area of the window. A window is
  520. * insecure if there is a security manager, and the security
  521. * manager's <code>checkTopLevelWindow</code> method returns
  522. * <code>false</code> when this window is passed to it as an
  523. * argument.
  524. * <p>
  525. * If the window is secure, then <code>getWarningString</code>
  526. * returns <code>null</code>. If the window is insecure, this
  527. * method checks for the system property
  528. * <code>awt.appletWarning</code>
  529. * and returns the string value of that property.
  530. * @return the warning string for this window.
  531. * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
  532. */
  533. public final String getWarningString() {
  534. return warningString;
  535. }
  536. private void setWarningString() {
  537. warningString = null;
  538. SecurityManager sm = System.getSecurityManager();
  539. if (sm != null) {
  540. if (!sm.checkTopLevelWindow(this)) {
  541. // make sure the privileged action is only
  542. // for getting the property! We don't want the
  543. // above checkTopLevelWindow call to always succeed!
  544. warningString = (String) AccessController.doPrivileged(
  545. new GetPropertyAction("awt.appletWarning",
  546. "Java Applet Window"));
  547. }
  548. }
  549. }
  550. /**
  551. * Gets the <code>Locale</code> object that is associated
  552. * with this window, if the locale has been set.
  553. * If no locale has been set, then the default locale
  554. * is returned.
  555. * @return the locale that is set for this window.
  556. * @see java.util.Locale
  557. * @since JDK1.1
  558. */
  559. public Locale getLocale() {
  560. if (this.locale == null) {
  561. return Locale.getDefault();
  562. }
  563. return this.locale;
  564. }
  565. /**
  566. * Gets the input context for this window. A window always has an input context,
  567. * which is shared by subcomponents unless they create and set their own.
  568. * @see Component#getInputContext
  569. * @since 1.2
  570. */
  571. public InputContext getInputContext() {
  572. if (inputContext == null) {
  573. synchronized (inputContextLock) {
  574. if (inputContext == null) {
  575. inputContext = InputContext.getInstance();
  576. }
  577. }
  578. }
  579. return inputContext;
  580. }
  581. /**
  582. * Set the cursor image to a specified cursor.
  583. * @param <code>cursor</code> One of the constants defined
  584. * by the <code>Cursor</code> class. If this parameter is null
  585. * then the cursor for this window will be set to the type
  586. * Cursor.DEFAULT_CURSOR.
  587. * @see java.awt.Component#getCursor
  588. * @see java.awt.Cursor
  589. * @since JDK1.1
  590. */
  591. public void setCursor(Cursor cursor) {
  592. if (cursor == null) {
  593. cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  594. }
  595. super.setCursor(cursor);
  596. }
  597. /**
  598. * Returns the owner of this window.
  599. */
  600. public Window getOwner() {
  601. return (Window)parent;
  602. }
  603. /**
  604. * Return an array containing all the windows this
  605. * window currently owns.
  606. * @since 1.2
  607. */
  608. public Window[] getOwnedWindows() {
  609. Window realCopy[];
  610. synchronized(ownedWindowList) {
  611. // Recall that ownedWindowList is actually a Vector of
  612. // WeakReferences and calling get() on one of these references
  613. // may return null. Make two arrays-- one the size of the
  614. // Vector (fullCopy with size fullSize), and one the size of
  615. // all non-null get()s (realCopy with size realSize).
  616. int fullSize = ownedWindowList.size();
  617. int realSize = 0;
  618. Window fullCopy[] = new Window[fullSize];
  619. for (int i = 0; i < fullSize; i++) {
  620. fullCopy[realSize] = (Window) (((WeakReference)
  621. (ownedWindowList.elementAt(i))).get());
  622. if (fullCopy[realSize] != null) {
  623. realSize++;
  624. }
  625. }
  626. if (fullSize != realSize) {
  627. realCopy = new Window[realSize];
  628. System.arraycopy(fullCopy, 0, realCopy, 0, realSize);
  629. } else {
  630. realCopy = fullCopy;
  631. }
  632. }
  633. return realCopy;
  634. }
  635. /**
  636. * Adds the specified window listener to receive window events from
  637. * this window.
  638. * If l is null, no exception is thrown and no action is performed.
  639. *
  640. * @param l the window listener
  641. */
  642. public synchronized void addWindowListener(WindowListener l) {
  643. if (l == null) {
  644. return;
  645. }
  646. windowListener = AWTEventMulticaster.add(windowListener, l);
  647. newEventsOnly = true;
  648. }
  649. /**
  650. * Removes the specified window listener so that it no longer
  651. * receives window events from this window.
  652. * If l is null, no exception is thrown and no action is performed.
  653. *
  654. * @param l the window listener
  655. */
  656. public synchronized void removeWindowListener(WindowListener l) {
  657. if (l == null) {
  658. return;
  659. }
  660. windowListener = AWTEventMulticaster.remove(windowListener, l);
  661. }
  662. /**
  663. * Return an array of all the listeners that were added to the Window
  664. * with addXXXListener(), where XXX is the name of the <code>listenerType</code>
  665. * argument. For example, to get all of the WindowListener(s) for the
  666. * given Window <code>w</code>, one would write:
  667. * <pre>
  668. * WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class))
  669. * </pre>
  670. * If no such listener list exists, then an empty array is returned.
  671. *
  672. * @param listenerType Type of listeners requested
  673. * @return all of the listeners of the specified type supported by this text field
  674. * @since 1.3
  675. */
  676. public EventListener[] getListeners(Class listenerType) {
  677. EventListener l = null;
  678. if (listenerType == WindowListener.class) {
  679. l = windowListener;
  680. } else {
  681. return super.getListeners(listenerType);
  682. }
  683. return AWTEventMulticaster.getListeners(l, listenerType);
  684. }
  685. // REMIND: remove when filtering is handled at lower level
  686. boolean eventEnabled(AWTEvent e) {
  687. switch(e.id) {
  688. case WindowEvent.WINDOW_OPENED:
  689. case WindowEvent.WINDOW_CLOSING:
  690. case WindowEvent.WINDOW_CLOSED:
  691. case WindowEvent.WINDOW_ICONIFIED:
  692. case WindowEvent.WINDOW_DEICONIFIED:
  693. case WindowEvent.WINDOW_ACTIVATED:
  694. case WindowEvent.WINDOW_DEACTIVATED:
  695. if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
  696. windowListener != null) {
  697. return true;
  698. }
  699. return false;
  700. default:
  701. break;
  702. }
  703. return super.eventEnabled(e);
  704. }
  705. boolean isActive() {
  706. return active;
  707. }
  708. /**
  709. * Processes events on this window. If the event is an WindowEvent,
  710. * it invokes the processWindowEvent method, else it invokes its
  711. * superclass's processEvent.
  712. * @param e the event
  713. */
  714. protected void processEvent(AWTEvent e) {
  715. if (e instanceof WindowEvent) {
  716. processWindowEvent((WindowEvent)e);
  717. return;
  718. }
  719. super.processEvent(e);
  720. }
  721. /**
  722. * Processes window events occurring on this window by
  723. * dispatching them to any registered WindowListener objects.
  724. * NOTE: This method will not be called unless window events
  725. * are enabled for this component; this happens when one of the
  726. * following occurs:
  727. * a) A WindowListener object is registered via addWindowListener()
  728. * b) Window events are enabled via enableEvents()
  729. * @see Component#enableEvents
  730. * @param e the window event
  731. */
  732. protected void processWindowEvent(WindowEvent e) {
  733. if (windowListener != null) {
  734. switch(e.getID()) {
  735. case WindowEvent.WINDOW_OPENED:
  736. windowListener.windowOpened(e);
  737. break;
  738. case WindowEvent.WINDOW_CLOSING:
  739. windowListener.windowClosing(e);
  740. break;
  741. case WindowEvent.WINDOW_CLOSED:
  742. windowListener.windowClosed(e);
  743. break;
  744. case WindowEvent.WINDOW_ICONIFIED:
  745. windowListener.windowIconified(e);
  746. break;
  747. case WindowEvent.WINDOW_DEICONIFIED:
  748. windowListener.windowDeiconified(e);
  749. break;
  750. case WindowEvent.WINDOW_ACTIVATED:
  751. windowListener.windowActivated(e);
  752. break;
  753. case WindowEvent.WINDOW_DEACTIVATED:
  754. windowListener.windowDeactivated(e);
  755. break;
  756. default:
  757. break;
  758. }
  759. }
  760. }
  761. void preProcessKeyEvent(KeyEvent e) {
  762. // Dump the list of child windows to System.out.
  763. if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
  764. e.isControlDown() && e.isShiftDown() &&
  765. e.getID() == KeyEvent.KEY_PRESSED) {
  766. list(System.out, 0);
  767. }
  768. }
  769. void postProcessKeyEvent(KeyEvent e) {
  770. WindowPeer peer = (WindowPeer)this.peer;
  771. if (peer == null)
  772. return;
  773. switch(peer.handleFocusTraversalEvent(e)) {
  774. case WindowPeer.IGNORE_EVENT:
  775. default:
  776. break;
  777. case WindowPeer.CONSUME_EVENT:
  778. e.consume();
  779. break;
  780. case WindowPeer.FOCUS_NEXT:
  781. if (focusMgr.focusNext())
  782. e.consume();
  783. break;
  784. case WindowPeer.FOCUS_PREVIOUS:
  785. if (focusMgr.focusPrevious())
  786. e.consume();
  787. break;
  788. }
  789. return;
  790. }
  791. void setFocusOwner(Component c) {
  792. focusMgr.setFocusOwner(c);
  793. }
  794. void transferFocus(Component base) {
  795. nextFocus(base);
  796. }
  797. /**
  798. * Returns the child component of this Window which has focus if and
  799. * only if this Window is active.
  800. * @return the component with focus, or null if no children have focus
  801. * assigned to them.
  802. */
  803. public Component getFocusOwner() {
  804. if (active)
  805. return focusMgr.getFocusOwner();
  806. else
  807. return null;
  808. }
  809. /**
  810. * @deprecated As of JDK version 1.1,
  811. * replaced by <code>transferFocus(Component)</code>.
  812. */
  813. void nextFocus(Component base) {
  814. focusMgr.focusNext(base);
  815. }
  816. /*
  817. * Dispatches an event to this window or one of its sub components.
  818. * @param e the event
  819. */
  820. void dispatchEventImpl(AWTEvent e) {
  821. switch(e.getID()) {
  822. case FocusEvent.FOCUS_GAINED:
  823. setFocusOwner(this);
  824. break;
  825. case ComponentEvent.COMPONENT_RESIZED:
  826. invalidate();
  827. validate();
  828. repaint();
  829. break;
  830. case WindowEvent.WINDOW_ACTIVATED:
  831. active = true;
  832. /*
  833. Calling this messes up focus on Solaris
  834. focusMgr.activateFocus();
  835. */
  836. break;
  837. case WindowEvent.WINDOW_DEACTIVATED:
  838. active = false;
  839. break;
  840. default:
  841. break;
  842. }
  843. super.dispatchEventImpl(e);
  844. }
  845. /**
  846. * @deprecated As of JDK version 1.1
  847. * replaced by <code>dispatchEvent(AWTEvent)</code>.
  848. */
  849. public boolean postEvent(Event e) {
  850. if (handleEvent(e)) {
  851. e.consume();
  852. return true;
  853. }
  854. return false;
  855. }
  856. /**
  857. * Checks if this Window is showing on screen.
  858. * @see java.awt.Component#setVisible(boolean)
  859. */
  860. public boolean isShowing() {
  861. return visible;
  862. }
  863. /**
  864. * Apply the settings in the given ResourceBundle to this Window.
  865. * Currently, this applies the ResourceBundle's ComponentOrientation
  866. * to this Window and all components contained within it.
  867. *
  868. * @see java.awt.ComponentOrientation
  869. * @since 1.2
  870. */
  871. public void applyResourceBundle(ResourceBundle rb) {
  872. // A package-visible utility on Container does all the work
  873. applyOrientation(ComponentOrientation.getOrientation(rb));
  874. }
  875. /**
  876. * Load the ResourceBundle with the given name using the default locale
  877. * and apply its settings to this window.
  878. * Currently, this applies the ResourceBundle's ComponentOrientation
  879. * to this Window and all components contained within it.
  880. *
  881. * @see java.awt.ComponentOrientation
  882. * @since 1.2
  883. */
  884. public void applyResourceBundle(String rbName) {
  885. applyResourceBundle(ResourceBundle.getBundle(rbName));
  886. }
  887. /*
  888. * Support for tracking all windows owned by this window
  889. */
  890. void addOwnedWindow(WeakReference weakWindow) {
  891. if (weakWindow != null) {
  892. synchronized(ownedWindowList) {
  893. // this if statement should really be an assert, but we don't
  894. // have asserts...
  895. if (!ownedWindowList.contains(weakWindow)) {
  896. ownedWindowList.addElement(weakWindow);
  897. }
  898. }
  899. }
  900. }
  901. void removeOwnedWindow(WeakReference weakWindow) {
  902. if (weakWindow != null) {
  903. // synchronized block not required since removeElement is
  904. // already synchronized
  905. ownedWindowList.removeElement(weakWindow);
  906. }
  907. }
  908. void connectOwnedWindow(Window child) {
  909. WeakReference weakChild = new WeakReference(child);
  910. child.weakThis = weakChild;
  911. child.parent = this;
  912. addOwnedWindow(weakChild);
  913. }
  914. /**
  915. * The window serialized data version.
  916. *
  917. * @serial
  918. */
  919. private int windowSerializedDataVersion = 1;
  920. /**
  921. * Writes default serializable fields to stream. Writes
  922. * a list of serializable ItemListener(s) as optional data.
  923. * The non-serializable ItemListener(s) are detected and
  924. * no attempt is made to serialize them. Write a list of
  925. * child Windows as optional data.
  926. *
  927. * @serialData Null terminated sequence of 0 or more pairs.
  928. * The pair consists of a String and Object.
  929. * The String indicates the type of object and
  930. * is one of the following :
  931. * itemListenerK indicating an ItemListener object.
  932. * @serialData Null terminated sequence of 0 or more pairs.
  933. * The pair consists of a String and Object.
  934. * The String indicates the type of object and
  935. * is one of the following :
  936. * ownedWindowK indicating a child Window object.
  937. *
  938. * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  939. * @see java.awt.Component.itemListenerK
  940. * @see java.awt.Component.ownedWindowK
  941. */
  942. private void writeObject(ObjectOutputStream s)
  943. throws IOException
  944. {
  945. s.defaultWriteObject();
  946. AWTEventMulticaster.save(s, windowListenerK, windowListener);
  947. s.writeObject(null);
  948. synchronized (ownedWindowList) {
  949. for (int i = 0; i < ownedWindowList.size(); i++) {
  950. Window child = (Window) (((WeakReference)
  951. (ownedWindowList.elementAt(i))).get());
  952. if (child != null) {
  953. s.writeObject(ownedWindowK);
  954. s.writeObject(child);
  955. }
  956. }
  957. }
  958. s.writeObject(null);
  959. }
  960. /**
  961. * Read the default ObjectInputStream, a possibly null listener to
  962. * receive item events fired by the Window, and a possibly null
  963. * list of child Windows.
  964. * Unrecognised keys or values will be Ignored.
  965. *
  966. * @see removeActionListener()
  967. * @see addActionListener()
  968. */
  969. private void readObject(ObjectInputStream s)
  970. throws ClassNotFoundException, IOException
  971. {
  972. s.defaultReadObject();
  973. ownedWindowList = new Vector();
  974. Object keyOrNull;
  975. while(null != (keyOrNull = s.readObject())) {
  976. String key = ((String)keyOrNull).intern();
  977. if (windowListenerK == key)
  978. addWindowListener((WindowListener)(s.readObject()));
  979. else // skip value for unrecognized key
  980. s.readObject();
  981. }
  982. try {
  983. while (null != (keyOrNull = s.readObject())) {
  984. String key = ((String)keyOrNull).intern();
  985. if (ownedWindowK == key)
  986. connectOwnedWindow((Window) s.readObject());
  987. else // skip value for unrecognized key
  988. s.readObject();
  989. }
  990. }
  991. catch (OptionalDataException e) {
  992. // 1.1 serialized form
  993. // ownedWindowList will be updated by Frame.readObject
  994. }
  995. setWarningString();
  996. inputContextLock = new Object();
  997. }
  998. /*
  999. * --- Accessibility Support ---
  1000. *
  1001. */
  1002. /**
  1003. * Gets the AccessibleContext associated with this Window.
  1004. * For windows, the AccessibleContext takes the form of an
  1005. * AccessibleAWTWindow.
  1006. * A new AccessibleAWTWindow instance is created if necessary.
  1007. *
  1008. * @return an AccessibleAWTWindow that serves as the
  1009. * AccessibleContext of this Window
  1010. */
  1011. public AccessibleContext getAccessibleContext() {
  1012. if (accessibleContext == null) {
  1013. accessibleContext = new AccessibleAWTWindow();
  1014. }
  1015. return accessibleContext;
  1016. }
  1017. /**
  1018. * This class implements accessibility support for the
  1019. * <code>Window</code> class. It provides an implementation of the
  1020. * Java Accessibility API appropriate to window user-interface elements.
  1021. */
  1022. protected class AccessibleAWTWindow extends AccessibleAWTContainer {
  1023. /**
  1024. * Get the role of this object.
  1025. *
  1026. * @return an instance of AccessibleRole describing the role of the
  1027. * object
  1028. * @see AccessibleRole
  1029. */
  1030. public AccessibleRole getAccessibleRole() {
  1031. return AccessibleRole.WINDOW;
  1032. }
  1033. /**
  1034. * Get the state of this object.
  1035. *
  1036. * @return an instance of AccessibleStateSet containing the current
  1037. * state set of the object
  1038. * @see AccessibleState
  1039. */
  1040. public AccessibleStateSet getAccessibleStateSet() {
  1041. AccessibleStateSet states = super.getAccessibleStateSet();
  1042. if (getFocusOwner() != null) {
  1043. states.add(AccessibleState.ACTIVE);
  1044. }
  1045. return states;
  1046. }
  1047. } // inner class AccessibleAWTWindow
  1048. /**
  1049. * This method returns the GraphicsConfiguration used by this Window.
  1050. */
  1051. public GraphicsConfiguration getGraphicsConfiguration() {
  1052. //NOTE: for multiscreen, this will need to take into account
  1053. //which screen the window is on/mostly on instead of returning the
  1054. //default or constructor argument config.
  1055. synchronized(getTreeLock()) {
  1056. if (graphicsConfig == null) {
  1057. graphicsConfig =
  1058. GraphicsEnvironment. getLocalGraphicsEnvironment().
  1059. getDefaultScreenDevice().
  1060. getDefaultConfiguration();
  1061. }
  1062. return graphicsConfig;
  1063. }
  1064. }
  1065. /**
  1066. * Reset this Window's GraphicsConfiguration to the default.
  1067. * Called from the Toolkit thread, so NO CLIENT CODE.
  1068. */
  1069. void resetGC() {
  1070. synchronized(getTreeLock()) {
  1071. graphicsConfig = GraphicsEnvironment.
  1072. getLocalGraphicsEnvironment().
  1073. getDefaultScreenDevice().
  1074. getDefaultConfiguration();
  1075. }
  1076. }
  1077. } // class Window
  1078. class FocusManager implements java.io.Serializable {
  1079. Container focusRoot;
  1080. Component focusOwner;
  1081. /*
  1082. * JDK 1.1 serialVersionUID
  1083. */
  1084. static final long serialVersionUID = 2491878825643557906L;
  1085. FocusManager(Container cont) {
  1086. focusRoot = cont;
  1087. }
  1088. /* Re-activate the last component with focus if it is still
  1089. * visible and active.
  1090. * If no component had focus yet, assign it to first component
  1091. * capable of receiving it (visible, active, focusable).
  1092. * If no visible, active, focusable components are present,
  1093. * assign focus to the focus root.
  1094. */
  1095. void activateFocus() {
  1096. boolean assigned = false;
  1097. if (focusOwner != null) {
  1098. if ((assigned = assignFocus(focusOwner, false)) != true) {
  1099. assigned = focusNext(focusOwner);
  1100. }
  1101. } else {
  1102. // assign to first component capable of taking it
  1103. assigned = focusForward(focusRoot);
  1104. }
  1105. if (!assigned) {
  1106. focusRoot.requestFocus();
  1107. }
  1108. }
  1109. synchronized void setFocusOwner(Component c) {
  1110. //System.out.println("FocusManager.setFocusOwner: "+c.name);
  1111. focusOwner = c;
  1112. }
  1113. Component getFocusOwner() {
  1114. return focusOwner;
  1115. }
  1116. boolean focusNext() {
  1117. return focusNext(focusOwner);
  1118. }
  1119. boolean focusNext(Component base) {
  1120. synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  1121. Component target = base;
  1122. if (target != null && target.parent != null) {
  1123. //System.out.println("FocusManager.focusNext: owner="+focusOwner);
  1124. do {
  1125. boolean found = false;
  1126. Container p = target.parent;
  1127. Component c;
  1128. for (int i = 0; i < p.ncomponents; i++) {
  1129. c = p.component[i];
  1130. if (found) {
  1131. if (assignFocus(c)) {
  1132. return true;
  1133. }
  1134. if (c instanceof Container &&
  1135. c.isVisible() &&
  1136. c.isEnabled()) {
  1137. if (focusForward((Container)c)) {
  1138. return true;
  1139. }
  1140. }
  1141. } else if (c == target) {
  1142. found = true;
  1143. }
  1144. }
  1145. target = p;
  1146. } while (target != focusRoot && target.parent != null);
  1147. }
  1148. // wrap-around
  1149. if (focusForward(focusRoot)) {
  1150. return true;
  1151. }
  1152. return false;
  1153. }
  1154. }
  1155. boolean focusPrevious() {
  1156. return focusPrevious(focusOwner);
  1157. }
  1158. boolean focusPrevious(Component base) {
  1159. synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  1160. Component target = base;
  1161. if (target != null && target.parent != null) {
  1162. do {
  1163. boolean found = false;
  1164. Container p = target.parent;
  1165. if (p != null) {
  1166. Component c;
  1167. for (int i = p.ncomponents-1; i >= 0; i--) {
  1168. c = p.component[i];
  1169. if (found) {
  1170. if (assignFocus(c)) {
  1171. return true;
  1172. }
  1173. if (c instanceof Container &&
  1174. c.isVisible() &&
  1175. c.isEnabled()) {
  1176. if (focusBackward((Container)c)) {
  1177. return true;
  1178. }
  1179. }
  1180. } else if (c == target) {
  1181. found = true;
  1182. }
  1183. }
  1184. }
  1185. target = p;
  1186. } while (target != null && target != focusRoot);
  1187. }
  1188. // wrap-around
  1189. if (focusBackward(focusRoot)) {
  1190. return true;
  1191. }
  1192. return false;
  1193. }
  1194. }
  1195. boolean assignFocus(Component c) {
  1196. return assignFocus(c, true);
  1197. }
  1198. synchronized boolean assignFocus(Component c, boolean requireTraversable) {
  1199. if (c.isVisible() && c.isEnabled() &&
  1200. (!requireTraversable || c.isFocusTraversable())) {
  1201. //System.out.println("FocusManager.assignFocus: "+c);
  1202. c.requestFocus();
  1203. return true;
  1204. }
  1205. return false;
  1206. }
  1207. synchronized boolean focusForward(Container cont) {
  1208. for (int i = 0; i < cont.ncomponents; i++) {
  1209. Component c = cont.component[i];
  1210. if (assignFocus(c)) {
  1211. return true;
  1212. }
  1213. if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  1214. if (focusForward((Container)c)) {
  1215. return true;
  1216. }
  1217. }
  1218. }
  1219. return false;
  1220. }
  1221. synchronized boolean focusBackward(Container cont) {
  1222. for (int i = cont.ncomponents-1; i >= 0; i--) {
  1223. Component c = cont.component[i];
  1224. if (assignFocus(c)) {
  1225. return true;
  1226. }
  1227. if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  1228. if (focusBackward((Container)c)) {
  1229. return true;
  1230. }
  1231. }
  1232. }
  1233. return false;
  1234. }
  1235. }