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