1 /* Window.java -- 2 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.awt; 40 41 import java.awt.event.ComponentEvent; 42 import java.awt.event.WindowEvent; 43 import java.awt.event.WindowFocusListener; 44 import java.awt.event.WindowListener; 45 import java.awt.event.WindowStateListener; 46 import java.awt.image.BufferStrategy; 47 import java.awt.peer.WindowPeer; 48 import java.lang.ref.Reference; 49 import java.lang.ref.WeakReference; 50 import java.util.EventListener; 51 import java.util.Iterator; 52 import java.util.Locale; 53 import java.util.ResourceBundle; 54 import java.util.Vector; 55 56 import javax.accessibility.Accessible; 57 import javax.accessibility.AccessibleContext; 58 import javax.accessibility.AccessibleRole; 59 import javax.accessibility.AccessibleState; 60 import javax.accessibility.AccessibleStateSet; 61 62 /** 63 * This class represents a top-level window with no decorations. 64 * 65 * @author Aaron M. Renn (arenn@urbanophile.com) 66 * @author Warren Levy (warrenl@cygnus.com) 67 */ 68 public class Window extends Container implements Accessible 69 { 70 private static final long serialVersionUID = 4497834738069338734L; 71 72 // Serialized fields, from Sun's serialization spec. 73 private String warningString = null; 74 private int windowSerializedDataVersion = 0; // FIXME 75 /** @since 1.2 */ 76 // private FocusManager focusMgr; // FIXME: what is this? 77 /** @since 1.2 */ 78 private int state = 0; 79 /** @since 1.4 */ 80 private boolean focusableWindowState = true; 81 /** @since 1.5 */ 82 private boolean alwaysOnTop = false; 83 84 // A list of other top-level windows owned by this window. 85 private transient Vector ownedWindows = new Vector(); 86 87 private transient WindowListener windowListener; 88 private transient WindowFocusListener windowFocusListener; 89 private transient WindowStateListener windowStateListener; 90 91 private transient boolean shown; 92 93 // This is package-private to avoid an accessor method. 94 transient Component windowFocusOwner; 95 96 /* 97 * The number used to generate the name returned by getName. 98 */ 99 private static transient long next_window_number; 100 101 protected class AccessibleAWTWindow extends AccessibleAWTContainer 102 { 103 private static final long serialVersionUID = 4215068635060671780L; 104 getAccessibleRole()105 public AccessibleRole getAccessibleRole() 106 { 107 return AccessibleRole.WINDOW; 108 } 109 getAccessibleStateSet()110 public AccessibleStateSet getAccessibleStateSet() 111 { 112 AccessibleStateSet states = super.getAccessibleStateSet(); 113 if (isActive()) 114 states.add(AccessibleState.ACTIVE); 115 return states; 116 } 117 } 118 119 /** 120 * This (package access) constructor is used by subclasses that want 121 * to build windows that do not have parents. Eg. toplevel 122 * application frames. Subclasses cannot call super(null), since 123 * null is an illegal argument. 124 */ Window()125 Window() 126 { 127 visible = false; 128 // Windows are the only Containers that default to being focus 129 // cycle roots. 130 focusCycleRoot = true; 131 setLayout(new BorderLayout()); 132 133 GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment(); 134 graphicsConfig = g.getDefaultScreenDevice().getDefaultConfiguration(); 135 } 136 Window(GraphicsConfiguration gc)137 Window(GraphicsConfiguration gc) 138 { 139 this(); 140 graphicsConfig = gc; 141 } 142 143 /** 144 * Initializes a new instance of <code>Window</code> with the specified 145 * parent. The window will initially be invisible. 146 * 147 * @param owner The owning <code>Frame</code> of this window. 148 * 149 * @exception IllegalArgumentException If the owner's GraphicsConfiguration 150 * is not from a screen device, or if owner is null; this exception is always 151 * thrown when GraphicsEnvironment.isHeadless returns true. 152 */ Window(Frame owner)153 public Window(Frame owner) 154 { 155 this (owner, owner.getGraphicsConfiguration ()); 156 } 157 158 /** 159 * Initializes a new instance of <code>Window</code> with the specified 160 * parent. The window will initially be invisible. 161 * 162 * @exception IllegalArgumentException If the owner's GraphicsConfiguration 163 * is not from a screen device, or if owner is null; this exception is always 164 * thrown when GraphicsEnvironment.isHeadless returns true. 165 * 166 * @since 1.2 167 */ Window(Window owner)168 public Window(Window owner) 169 { 170 this (owner, owner.getGraphicsConfiguration ()); 171 } 172 173 /** 174 * Initializes a new instance of <code>Window</code> with the specified 175 * parent. The window will initially be invisible. 176 * 177 * @exception IllegalArgumentException If owner is null or if gc is not from a 178 * screen device; this exception is always thrown when 179 * GraphicsEnvironment.isHeadless returns true. 180 * 181 * @since 1.3 182 */ Window(Window owner, GraphicsConfiguration gc)183 public Window(Window owner, GraphicsConfiguration gc) 184 { 185 this (); 186 187 synchronized (getTreeLock()) 188 { 189 if (owner == null) 190 throw new IllegalArgumentException ("owner must not be null"); 191 192 parent = owner; 193 owner.ownedWindows.add(new WeakReference(this)); 194 } 195 196 // FIXME: make this text visible in the window. 197 SecurityManager s = System.getSecurityManager(); 198 if (s != null && ! s.checkTopLevelWindow(this)) 199 warningString = System.getProperty("awt.appletWarning"); 200 201 if (gc != null 202 && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN) 203 throw new IllegalArgumentException ("gc must be from a screen device"); 204 205 if (gc == null) 206 graphicsConfig = GraphicsEnvironment.getLocalGraphicsEnvironment() 207 .getDefaultScreenDevice() 208 .getDefaultConfiguration(); 209 else 210 graphicsConfig = gc; 211 } 212 213 /** 214 * Creates the native peer for this window. 215 */ addNotify()216 public void addNotify() 217 { 218 if (peer == null) 219 peer = getToolkit().createWindow(this); 220 super.addNotify(); 221 } 222 223 /** 224 * Relays out this window's child components at their preferred size. 225 * 226 * @specnote pack() doesn't appear to be called internally by show(), so 227 * we duplicate some of the functionality. 228 */ pack()229 public void pack() 230 { 231 if (parent != null && !parent.isDisplayable()) 232 parent.addNotify(); 233 if (peer == null) 234 addNotify(); 235 236 setSize(getPreferredSize()); 237 238 validate(); 239 } 240 241 /** 242 * Shows on-screen this window and any of its owned windows for whom 243 * isVisible returns true. 244 * @specnote: Deprecated starting in 1.5. 245 */ 246 @Deprecated show()247 public void show() 248 { 249 synchronized (getTreeLock()) 250 { 251 if (peer == null) 252 addNotify(); 253 254 validate(); 255 if (visible) 256 toFront(); 257 else 258 { 259 super.show(); 260 // Show visible owned windows. 261 Iterator e = ownedWindows.iterator(); 262 while (e.hasNext()) 263 { 264 Window w = (Window) (((Reference) e.next()).get()); 265 if (w != null) 266 { 267 if (w.isVisible()) 268 w.getPeer().setVisible(true); 269 } 270 else 271 // Remove null weak reference from ownedWindows. 272 // Unfortunately this can't be done in the Window's 273 // finalize method because there is no way to guarantee 274 // synchronous access to ownedWindows there. 275 e.remove(); 276 } 277 } 278 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 279 manager.setGlobalFocusedWindow(this); 280 281 if (! shown) 282 { 283 FocusTraversalPolicy policy = getFocusTraversalPolicy(); 284 Component initialFocusOwner = null; 285 286 if (policy != null) 287 initialFocusOwner = policy.getInitialComponent(this); 288 289 if (initialFocusOwner != null) 290 initialFocusOwner.requestFocusInWindow(); 291 292 // Post WINDOW_OPENED from here. 293 if (windowListener != null 294 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) 295 { 296 WindowEvent ev = new WindowEvent(this, 297 WindowEvent.WINDOW_OPENED); 298 Toolkit tk = Toolkit.getDefaultToolkit(); 299 tk.getSystemEventQueue().postEvent(ev); 300 } 301 shown = true; 302 } 303 } 304 } 305 306 /** 307 * @specnote: Deprecated starting in 1.5. 308 */ 309 @Deprecated hide()310 public void hide() 311 { 312 // Hide visible owned windows. 313 synchronized (getTreeLock ()) 314 { 315 Iterator e = ownedWindows.iterator(); 316 while(e.hasNext()) 317 { 318 Window w = (Window)(((Reference) e.next()).get()); 319 if (w != null) 320 { 321 if (w.isVisible() && w.getPeer() != null) 322 w.getPeer().setVisible(false); 323 } 324 else 325 e.remove(); 326 } 327 } 328 super.hide(); 329 } 330 331 /** 332 * Destroys any resources associated with this window. This includes 333 * all components in the window and all owned top-level windows. 334 */ dispose()335 public void dispose() 336 { 337 hide(); 338 339 synchronized (getTreeLock ()) 340 { 341 Iterator e = ownedWindows.iterator(); 342 while(e.hasNext()) 343 { 344 Window w = (Window)(((Reference) e.next()).get()); 345 if (w != null) 346 w.dispose(); 347 else 348 // Remove null weak reference from ownedWindows. 349 e.remove(); 350 } 351 352 for (int i = 0; i < ncomponents; ++i) 353 component[i].removeNotify(); 354 this.removeNotify(); 355 356 // Post WINDOW_CLOSED from here. 357 if (windowListener != null 358 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) 359 { 360 WindowEvent ev = new WindowEvent(this, 361 WindowEvent.WINDOW_CLOSED); 362 Toolkit tk = Toolkit.getDefaultToolkit(); 363 tk.getSystemEventQueue().postEvent(ev); 364 } 365 } 366 } 367 368 /** 369 * Sends this window to the back so that all other windows display in 370 * front of it. 371 * 372 * If the window is set to be always-on-top, this will remove its 373 * always-on-top status. 374 */ toBack()375 public void toBack() 376 { 377 if (peer != null) 378 { 379 if( alwaysOnTop ) 380 setAlwaysOnTop( false ); 381 ( (WindowPeer) peer ).toBack(); 382 } 383 } 384 385 /** 386 * Brings this window to the front so that it displays in front of 387 * any other windows. 388 */ toFront()389 public void toFront() 390 { 391 if (peer != null) 392 ( (WindowPeer) peer ).toFront(); 393 } 394 395 /** 396 * Returns the toolkit used to create this window. 397 * 398 * @return The toolkit used to create this window. 399 * 400 * @specnote Unlike Component.getToolkit, this implementation always 401 * returns the value of Toolkit.getDefaultToolkit(). 402 */ getToolkit()403 public Toolkit getToolkit() 404 { 405 return Toolkit.getDefaultToolkit(); 406 } 407 408 /** 409 * Returns the warning string that will be displayed if this window is 410 * popped up by an unsecure applet or application. 411 * 412 * @return The unsecure window warning message. 413 */ getWarningString()414 public final String getWarningString() 415 { 416 return warningString; 417 } 418 419 /** 420 * Returns the locale that this window is configured for. 421 * 422 * @return The locale this window is configured for. 423 */ getLocale()424 public Locale getLocale() 425 { 426 return locale == null ? Locale.getDefault() : locale; 427 } 428 429 /* 430 /** @since 1.2 431 public InputContext getInputContext() 432 { 433 // FIXME 434 } 435 */ 436 437 /** 438 * Sets the cursor for this window to the specifiec cursor. 439 * 440 * @param cursor The new cursor for this window. 441 */ setCursor(Cursor cursor)442 public void setCursor(Cursor cursor) 443 { 444 super.setCursor(cursor); 445 } 446 getOwner()447 public Window getOwner() 448 { 449 return (Window) parent; 450 } 451 452 /** @since 1.2 */ getOwnedWindows()453 public Window[] getOwnedWindows() 454 { 455 Window [] trimmedList; 456 synchronized (getTreeLock ()) 457 { 458 // Windows with non-null weak references in ownedWindows. 459 Window [] validList = new Window [ownedWindows.size()]; 460 461 Iterator e = ownedWindows.iterator(); 462 int numValid = 0; 463 while (e.hasNext()) 464 { 465 Window w = (Window)(((Reference) e.next()).get()); 466 if (w != null) 467 validList[numValid++] = w; 468 else 469 // Remove null weak reference from ownedWindows. 470 e.remove(); 471 } 472 473 if (numValid != validList.length) 474 { 475 trimmedList = new Window [numValid]; 476 System.arraycopy (validList, 0, trimmedList, 0, numValid); 477 } 478 else 479 trimmedList = validList; 480 } 481 return trimmedList; 482 } 483 484 /** 485 * Adds the specified listener to the list of <code>WindowListeners</code> 486 * that will receive events for this window. 487 * 488 * @param listener The <code>WindowListener</code> to add. 489 */ addWindowListener(WindowListener listener)490 public synchronized void addWindowListener(WindowListener listener) 491 { 492 if (listener != null) 493 { 494 newEventsOnly = true; 495 windowListener = AWTEventMulticaster.add(windowListener, listener); 496 } 497 } 498 499 /** 500 * Removes the specified listener from the list of 501 * <code>WindowListeners</code> that will receive events for this window. 502 * 503 * @param listener The <code>WindowListener</code> to remove. 504 */ removeWindowListener(WindowListener listener)505 public synchronized void removeWindowListener(WindowListener listener) 506 { 507 windowListener = AWTEventMulticaster.remove(windowListener, listener); 508 } 509 510 /** 511 * Returns an array of all the window listeners registered on this window. 512 * 513 * @since 1.4 514 */ getWindowListeners()515 public synchronized WindowListener[] getWindowListeners() 516 { 517 return (WindowListener[]) 518 AWTEventMulticaster.getListeners(windowListener, 519 WindowListener.class); 520 } 521 522 /** 523 * Returns an array of all the window focus listeners registered on this 524 * window. 525 * 526 * @since 1.4 527 */ getWindowFocusListeners()528 public synchronized WindowFocusListener[] getWindowFocusListeners() 529 { 530 return (WindowFocusListener[]) 531 AWTEventMulticaster.getListeners(windowFocusListener, 532 WindowFocusListener.class); 533 } 534 535 /** 536 * Returns an array of all the window state listeners registered on this 537 * window. 538 * 539 * @since 1.4 540 */ getWindowStateListeners()541 public synchronized WindowStateListener[] getWindowStateListeners() 542 { 543 return (WindowStateListener[]) 544 AWTEventMulticaster.getListeners(windowStateListener, 545 WindowStateListener.class); 546 } 547 548 /** 549 * Adds the specified listener to this window. 550 */ addWindowFocusListener(WindowFocusListener wfl)551 public void addWindowFocusListener (WindowFocusListener wfl) 552 { 553 if (wfl != null) 554 { 555 newEventsOnly = true; 556 windowFocusListener = AWTEventMulticaster.add (windowFocusListener, 557 wfl); 558 } 559 } 560 561 /** 562 * Adds the specified listener to this window. 563 * 564 * @since 1.4 565 */ addWindowStateListener(WindowStateListener wsl)566 public void addWindowStateListener (WindowStateListener wsl) 567 { 568 if (wsl != null) 569 { 570 newEventsOnly = true; 571 windowStateListener = AWTEventMulticaster.add (windowStateListener, 572 wsl); 573 } 574 } 575 576 /** 577 * Removes the specified listener from this window. 578 */ removeWindowFocusListener(WindowFocusListener wfl)579 public void removeWindowFocusListener (WindowFocusListener wfl) 580 { 581 windowFocusListener = AWTEventMulticaster.remove (windowFocusListener, wfl); 582 } 583 584 /** 585 * Removes the specified listener from this window. 586 * 587 * @since 1.4 588 */ removeWindowStateListener(WindowStateListener wsl)589 public void removeWindowStateListener (WindowStateListener wsl) 590 { 591 windowStateListener = AWTEventMulticaster.remove (windowStateListener, wsl); 592 } 593 594 /** 595 * Returns an array of all the objects currently registered as FooListeners 596 * upon this Window. FooListeners are registered using the addFooListener 597 * method. 598 * 599 * @exception ClassCastException If listenerType doesn't specify a class or 600 * interface that implements java.util.EventListener. 601 * 602 * @since 1.3 603 */ getListeners(Class<T> listenerType)604 public <T extends EventListener> T[] getListeners(Class<T> listenerType) 605 { 606 if (listenerType == WindowListener.class) 607 return (T[]) getWindowListeners(); 608 return super.getListeners(listenerType); 609 } 610 dispatchEventImpl(AWTEvent e)611 void dispatchEventImpl(AWTEvent e) 612 { 613 if (e.getID() == ComponentEvent.COMPONENT_RESIZED) 614 { 615 invalidate(); 616 validate(); 617 } 618 super.dispatchEventImpl(e); 619 } 620 621 /** 622 * Processes the specified event for this window. If the event is an 623 * instance of <code>WindowEvent</code>, then 624 * <code>processWindowEvent()</code> is called to process the event, 625 * otherwise the superclass version of this method is invoked. 626 * 627 * @param evt The event to process. 628 */ processEvent(AWTEvent evt)629 protected void processEvent(AWTEvent evt) 630 { 631 if (evt instanceof WindowEvent) 632 { 633 WindowEvent we = (WindowEvent) evt; 634 switch (evt.getID()) 635 { 636 case WindowEvent.WINDOW_OPENED: 637 case WindowEvent.WINDOW_CLOSED: 638 case WindowEvent.WINDOW_CLOSING: 639 case WindowEvent.WINDOW_ICONIFIED: 640 case WindowEvent.WINDOW_DEICONIFIED: 641 case WindowEvent.WINDOW_ACTIVATED: 642 case WindowEvent.WINDOW_DEACTIVATED: 643 processWindowEvent(we); 644 break; 645 case WindowEvent.WINDOW_GAINED_FOCUS: 646 case WindowEvent.WINDOW_LOST_FOCUS: 647 processWindowFocusEvent(we); 648 break; 649 case WindowEvent.WINDOW_STATE_CHANGED: 650 processWindowStateEvent(we); 651 break; 652 } 653 } 654 else 655 super.processEvent(evt); 656 } 657 658 /** 659 * Dispatches this event to any listeners that are listening for 660 * <code>WindowEvents</code> on this window. This method only gets 661 * invoked if it is enabled via <code>enableEvents()</code> or if 662 * a listener has been added. 663 * 664 * @param evt The event to process. 665 */ processWindowEvent(WindowEvent evt)666 protected void processWindowEvent(WindowEvent evt) 667 { 668 if (windowListener != null) 669 { 670 switch (evt.getID()) 671 { 672 case WindowEvent.WINDOW_ACTIVATED: 673 windowListener.windowActivated(evt); 674 break; 675 case WindowEvent.WINDOW_CLOSED: 676 windowListener.windowClosed(evt); 677 break; 678 case WindowEvent.WINDOW_CLOSING: 679 windowListener.windowClosing(evt); 680 break; 681 case WindowEvent.WINDOW_DEACTIVATED: 682 windowListener.windowDeactivated(evt); 683 break; 684 case WindowEvent.WINDOW_DEICONIFIED: 685 windowListener.windowDeiconified(evt); 686 break; 687 case WindowEvent.WINDOW_ICONIFIED: 688 windowListener.windowIconified(evt); 689 break; 690 case WindowEvent.WINDOW_OPENED: 691 windowListener.windowOpened(evt); 692 break; 693 } 694 } 695 } 696 697 /** 698 * Identifies if this window is active. The active window is a Frame or 699 * Dialog that has focus or owns the active window. 700 * 701 * @return true if active, else false. 702 * @since 1.4 703 */ isActive()704 public boolean isActive() 705 { 706 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 707 return manager.getActiveWindow() == this; 708 } 709 710 /** 711 * Identifies if this window is focused. A window is focused if it is the 712 * focus owner or it contains the focus owner. 713 * 714 * @return true if focused, else false. 715 * @since 1.4 716 */ isFocused()717 public boolean isFocused() 718 { 719 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 720 return manager.getFocusedWindow() == this; 721 } 722 723 /** 724 * Returns the child window that has focus if this window is active. 725 * This method returns <code>null</code> if this window is not active 726 * or no children have focus. 727 * 728 * @return The component that has focus, or <code>null</code> if no 729 * component has focus. 730 */ getFocusOwner()731 public Component getFocusOwner () 732 { 733 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 734 735 Window activeWindow = manager.getActiveWindow (); 736 737 // The currently-focused Component belongs to the active Window. 738 if (activeWindow == this) 739 return manager.getFocusOwner (); 740 else 741 return null; 742 } 743 744 /** 745 * Returns the child component of this window that would receive 746 * focus if this window were to become focused. If the window 747 * already has the top-level focus, then this method returns the 748 * same component as getFocusOwner. If no child component has 749 * requested focus within the window, then the initial focus owner 750 * is returned. If this is a non-focusable window, this method 751 * returns null. 752 * 753 * @return the child component of this window that most recently had 754 * the focus, or <code>null</code> 755 * @since 1.4 756 */ getMostRecentFocusOwner()757 public Component getMostRecentFocusOwner () 758 { 759 return windowFocusOwner; 760 } 761 762 /** 763 * Set the focus owner for this window. This method is used to 764 * remember which component was focused when this window lost 765 * top-level focus, so that when it regains top-level focus the same 766 * child component can be refocused. 767 * 768 * @param windowFocusOwner the component in this window that owns 769 * the focus. 770 */ setFocusOwner(Component windowFocusOwner)771 void setFocusOwner (Component windowFocusOwner) 772 { 773 this.windowFocusOwner = windowFocusOwner; 774 } 775 776 /** 777 * Post a Java 1.0 event to the event queue. 778 * 779 * @param e The event to post. 780 * 781 * @deprecated 782 */ postEvent(Event e)783 public boolean postEvent(Event e) 784 { 785 return handleEvent (e); 786 } 787 788 /** 789 * Tests whether or not this window is visible on the screen. 790 * 791 * In contrast to the normal behaviour of Container, which is that 792 * a container is showing if its parent is visible and showing, a Window 793 * is even showing, if its parent (i.e. an invisible Frame) is not showing. 794 * 795 * @return <code>true</code> if this window is visible, <code>false</code> 796 * otherwise. 797 */ isShowing()798 public boolean isShowing() 799 { 800 return isVisible(); 801 } 802 setLocationRelativeTo(Component c)803 public void setLocationRelativeTo(Component c) 804 { 805 int x = 0; 806 int y = 0; 807 808 if (c == null || !c.isShowing()) 809 { 810 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 811 Point center = ge.getCenterPoint(); 812 x = center.x - (width / 2); 813 y = center.y - (height / 2); 814 } 815 else 816 { 817 int cWidth = c.getWidth(); 818 int cHeight = c.getHeight(); 819 Dimension screenSize = getToolkit().getScreenSize(); 820 821 x = c.getLocationOnScreen().x; 822 y = c.getLocationOnScreen().y; 823 824 // If bottom of component is cut off, window placed 825 // on the left or the right side of component 826 if ((y + cHeight) > screenSize.height) 827 { 828 // If the right side of the component is closer to the center 829 if ((screenSize.width / 2 - x) <= 0) 830 { 831 if ((x - width) >= 0) 832 x -= width; 833 else 834 x = 0; 835 } 836 else 837 { 838 if ((x + cWidth + width) <= screenSize.width) 839 x += cWidth; 840 else 841 x = screenSize.width - width; 842 } 843 844 y = screenSize.height - height; 845 } 846 else if (cWidth > width || cHeight > height) 847 { 848 // If right side of component is cut off 849 if ((x + width) > screenSize.width) 850 x = screenSize.width - width; 851 // If left side of component is cut off 852 else if (x < 0) 853 x = 0; 854 else 855 x += (cWidth - width) / 2; 856 857 y += (cHeight - height) / 2; 858 } 859 else 860 { 861 // If right side of component is cut off 862 if ((x + width) > screenSize.width) 863 x = screenSize.width - width; 864 // If left side of component is cut off 865 else if (x < 0 || (x - (width - cWidth) / 2) < 0) 866 x = 0; 867 else 868 x -= (width - cWidth) / 2; 869 870 if ((y - (height - cHeight) / 2) > 0) 871 y -= (height - cHeight) / 2; 872 else 873 y = 0; 874 } 875 } 876 877 setLocation(x, y); 878 } 879 880 /** 881 * A BltBufferStrategy for windows. 882 */ 883 private class WindowBltBufferStrategy extends BltBufferStrategy 884 { 885 /** 886 * Creates a block transfer strategy for this window. 887 * 888 * @param numBuffers the number of buffers in this strategy 889 * @param accelerated true if the buffer should be accelerated, 890 * false otherwise 891 */ WindowBltBufferStrategy(int numBuffers, boolean accelerated)892 WindowBltBufferStrategy(int numBuffers, boolean accelerated) 893 { 894 super(numBuffers, 895 new BufferCapabilities(new ImageCapabilities(accelerated), 896 new ImageCapabilities(accelerated), 897 BufferCapabilities.FlipContents.COPIED)); 898 } 899 } 900 901 /** 902 * A FlipBufferStrategy for windows. 903 */ 904 private class WindowFlipBufferStrategy extends FlipBufferStrategy 905 { 906 /** 907 * Creates a flip buffer strategy for this window. 908 * 909 * @param numBuffers the number of buffers in this strategy 910 * 911 * @throws AWTException if the requested number of buffers is not 912 * supported 913 */ WindowFlipBufferStrategy(int numBuffers)914 WindowFlipBufferStrategy(int numBuffers) 915 throws AWTException 916 { 917 super(numBuffers, 918 new BufferCapabilities(new ImageCapabilities(true), 919 new ImageCapabilities(true), 920 BufferCapabilities.FlipContents.COPIED)); 921 } 922 } 923 924 /** 925 * Creates a buffering strategy that manages how this window is 926 * repainted. This method attempts to create the optimum strategy 927 * based on the desired number of buffers. Hardware or software 928 * acceleration may be used. 929 * 930 * createBufferStrategy attempts different levels of optimization, 931 * but guarantees that some strategy with the requested number of 932 * buffers will be created even if it is not optimal. First it 933 * attempts to create a page flipping strategy, then an accelerated 934 * blitting strategy, then an unaccelerated blitting strategy. 935 * 936 * Calling this method causes any existing buffer strategy to be 937 * destroyed. 938 * 939 * @param numBuffers the number of buffers in this strategy 940 * 941 * @throws IllegalArgumentException if requested number of buffers 942 * is less than one 943 * @throws IllegalStateException if this window is not displayable 944 * 945 * @since 1.4 946 */ createBufferStrategy(int numBuffers)947 public void createBufferStrategy(int numBuffers) 948 { 949 if (numBuffers < 1) 950 throw new IllegalArgumentException("Window.createBufferStrategy: number" 951 + " of buffers is less than one"); 952 953 if (!isDisplayable()) 954 throw new IllegalStateException("Window.createBufferStrategy: window is" 955 + " not displayable"); 956 957 BufferStrategy newStrategy = null; 958 959 // try a flipping strategy 960 try 961 { 962 newStrategy = new WindowFlipBufferStrategy(numBuffers); 963 } 964 catch (AWTException e) 965 { 966 } 967 968 // fall back to an accelerated blitting strategy 969 if (newStrategy == null) 970 newStrategy = new WindowBltBufferStrategy(numBuffers, true); 971 972 bufferStrategy = newStrategy; 973 } 974 975 /** 976 * Creates a buffering strategy that manages how this window is 977 * repainted. This method attempts to create a strategy based on 978 * the specified capabilities and throws an exception if the 979 * requested strategy is not supported. 980 * 981 * Calling this method causes any existing buffer strategy to be 982 * destroyed. 983 * 984 * @param numBuffers the number of buffers in this strategy 985 * @param caps the requested buffering capabilities 986 * 987 * @throws AWTException if the requested capabilities are not 988 * supported 989 * @throws IllegalArgumentException if requested number of buffers 990 * is less than one or if caps is null 991 * 992 * @since 1.4 993 */ createBufferStrategy(int numBuffers, BufferCapabilities caps)994 public void createBufferStrategy(int numBuffers, BufferCapabilities caps) 995 throws AWTException 996 { 997 if (numBuffers < 1) 998 throw new IllegalArgumentException("Window.createBufferStrategy: number" 999 + " of buffers is less than one"); 1000 1001 if (caps == null) 1002 throw new IllegalArgumentException("Window.createBufferStrategy:" 1003 + " capabilities object is null"); 1004 1005 // a flipping strategy was requested 1006 if (caps.isPageFlipping()) 1007 bufferStrategy = new WindowFlipBufferStrategy(numBuffers); 1008 else 1009 bufferStrategy = new WindowBltBufferStrategy(numBuffers, true); 1010 } 1011 1012 /** 1013 * Returns the buffer strategy used by the window. 1014 * 1015 * @return the buffer strategy. 1016 * @since 1.4 1017 */ getBufferStrategy()1018 public BufferStrategy getBufferStrategy() 1019 { 1020 return bufferStrategy; 1021 } 1022 1023 /** 1024 * @since 1.2 1025 * 1026 * @deprecated replaced by Component.applyComponentOrientation. 1027 */ applyResourceBundle(ResourceBundle rb)1028 public void applyResourceBundle(ResourceBundle rb) 1029 { 1030 applyComponentOrientation(ComponentOrientation.getOrientation(rb)); 1031 } 1032 1033 /** 1034 * @since 1.2 1035 * 1036 * @deprecated 1037 */ applyResourceBundle(String rbName)1038 public void applyResourceBundle(String rbName) 1039 { 1040 ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(), 1041 ClassLoader.getSystemClassLoader()); 1042 if (rb != null) 1043 applyResourceBundle(rb); 1044 } 1045 1046 /** 1047 * Gets the AccessibleContext associated with this <code>Window</code>. 1048 * The context is created, if necessary. 1049 * 1050 * @return the associated context 1051 */ getAccessibleContext()1052 public AccessibleContext getAccessibleContext() 1053 { 1054 /* Create the context if this is the first request */ 1055 if (accessibleContext == null) 1056 accessibleContext = new AccessibleAWTWindow(); 1057 return accessibleContext; 1058 } 1059 1060 /** 1061 * Get graphics configuration. The implementation for Window will 1062 * not ask any parent containers, since Window is a toplevel 1063 * window and not actually embedded in the parent component. 1064 */ getGraphicsConfiguration()1065 public GraphicsConfiguration getGraphicsConfiguration() 1066 { 1067 GraphicsConfiguration conf = graphicsConfig; 1068 if (conf == null) 1069 { 1070 conf = GraphicsEnvironment.getLocalGraphicsEnvironment() 1071 .getDefaultScreenDevice().getDefaultConfiguration(); 1072 graphicsConfig = conf; 1073 } 1074 return conf; 1075 } 1076 processWindowFocusEvent(WindowEvent event)1077 protected void processWindowFocusEvent(WindowEvent event) 1078 { 1079 if (windowFocusListener != null) 1080 { 1081 switch (event.getID ()) 1082 { 1083 case WindowEvent.WINDOW_GAINED_FOCUS: 1084 windowFocusListener.windowGainedFocus (event); 1085 break; 1086 1087 case WindowEvent.WINDOW_LOST_FOCUS: 1088 windowFocusListener.windowLostFocus (event); 1089 break; 1090 1091 default: 1092 break; 1093 } 1094 } 1095 } 1096 1097 /** 1098 * @since 1.4 1099 */ processWindowStateEvent(WindowEvent event)1100 protected void processWindowStateEvent(WindowEvent event) 1101 { 1102 if (windowStateListener != null 1103 && event.getID () == WindowEvent.WINDOW_STATE_CHANGED) 1104 windowStateListener.windowStateChanged (event); 1105 } 1106 1107 /** 1108 * Returns whether this <code>Window</code> can get the focus or not. 1109 * 1110 * @since 1.4 1111 */ isFocusableWindow()1112 public final boolean isFocusableWindow () 1113 { 1114 if (getFocusableWindowState () == false) 1115 return false; 1116 1117 if (this instanceof Dialog 1118 || this instanceof Frame) 1119 return true; 1120 1121 // FIXME: Implement more possible cases for returning true. 1122 1123 return false; 1124 } 1125 1126 /** 1127 * Returns the value of the focusableWindowState property. 1128 * 1129 * @since 1.4 1130 */ getFocusableWindowState()1131 public boolean getFocusableWindowState () 1132 { 1133 return focusableWindowState; 1134 } 1135 1136 /** 1137 * Sets the value of the focusableWindowState property. 1138 * 1139 * @since 1.4 1140 */ setFocusableWindowState(boolean focusableWindowState)1141 public void setFocusableWindowState (boolean focusableWindowState) 1142 { 1143 this.focusableWindowState = focusableWindowState; 1144 } 1145 1146 /** 1147 * Check whether this Container is a focus cycle root. 1148 * Returns always <code>true</code> as Windows are the 1149 * root of the focus cycle. 1150 * 1151 * @return Always <code>true</code>. 1152 * 1153 * @since 1.4 1154 */ isFocusCycleRoot()1155 public final boolean isFocusCycleRoot() 1156 { 1157 return true; 1158 } 1159 1160 /** 1161 * Set whether or not this Container is the root of a focus 1162 * traversal cycle. Windows are the root of the focus cycle 1163 * and therefore this method does nothing. 1164 * 1165 * @param focusCycleRoot ignored. 1166 * 1167 * @since 1.4 1168 */ setFocusCycleRoot(boolean focusCycleRoot)1169 public final void setFocusCycleRoot(boolean focusCycleRoot) 1170 { 1171 // calls to the method are ignored 1172 } 1173 1174 /** 1175 * Returns the root container that owns the focus cycle where this 1176 * component resides. Windows have no ancestors and this method 1177 * returns always <code>null</code>. 1178 * 1179 * @return Always <code>null</code>. 1180 * @since 1.4 1181 */ getFocusCycleRootAncestor()1182 public final Container getFocusCycleRootAncestor() 1183 { 1184 return null; 1185 } 1186 1187 /** 1188 * Returns whether the Windows is an always-on-top window, 1189 * meaning whether the window can be obscured by other windows or not. 1190 * 1191 * @return <code>true</code> if the windows is always-on-top, 1192 * <code>false</code> otherwise. 1193 * @since 1.5 1194 */ isAlwaysOnTop()1195 public final boolean isAlwaysOnTop() 1196 { 1197 return alwaysOnTop; 1198 } 1199 1200 /** 1201 * Sets the always-on-top state of this window (if supported). 1202 * 1203 * Setting a window to always-on-top means it will not be obscured 1204 * by any other windows (with the exception of other always-on-top 1205 * windows). Not all platforms may support this. 1206 * 1207 * If an window's always-on-top status is changed to false, the window 1208 * will remain at the front but not be anchored there. 1209 * 1210 * Calling toBack() on an always-on-top window will change its 1211 * always-on-top status to false. 1212 * 1213 * @since 1.5 1214 */ setAlwaysOnTop(boolean alwaysOnTop)1215 public final void setAlwaysOnTop(boolean alwaysOnTop) 1216 { 1217 SecurityManager sm = System.getSecurityManager(); 1218 if (sm != null) 1219 sm.checkPermission( new AWTPermission("setWindowAlwaysOnTop") ); 1220 1221 if( this.alwaysOnTop == alwaysOnTop ) 1222 return; 1223 1224 if( alwaysOnTop ) 1225 toFront(); 1226 1227 firePropertyChange("alwaysOnTop", this.alwaysOnTop, alwaysOnTop ); 1228 this.alwaysOnTop = alwaysOnTop; 1229 1230 if (peer != null) 1231 ( (WindowPeer) peer).updateAlwaysOnTop(); 1232 else 1233 System.out.println("Null peer?!"); 1234 } 1235 1236 /** 1237 * Generate a unique name for this window. 1238 * 1239 * @return A unique name for this window. 1240 */ generateName()1241 String generateName() 1242 { 1243 return "win" + getUniqueLong(); 1244 } 1245 1246 /** 1247 * Overridden to handle WindowEvents. 1248 * 1249 * @return <code>true</code> when the specified event type is enabled, 1250 * <code>false</code> otherwise 1251 */ eventTypeEnabled(int type)1252 boolean eventTypeEnabled(int type) 1253 { 1254 boolean enabled = false; 1255 switch (type) 1256 { 1257 case WindowEvent.WINDOW_OPENED: 1258 case WindowEvent.WINDOW_CLOSED: 1259 case WindowEvent.WINDOW_CLOSING: 1260 case WindowEvent.WINDOW_ICONIFIED: 1261 case WindowEvent.WINDOW_DEICONIFIED: 1262 case WindowEvent.WINDOW_ACTIVATED: 1263 case WindowEvent.WINDOW_DEACTIVATED: 1264 enabled = ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) 1265 || windowListener != null; 1266 break; 1267 case WindowEvent.WINDOW_GAINED_FOCUS: 1268 case WindowEvent.WINDOW_LOST_FOCUS: 1269 enabled = ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0) 1270 || windowFocusListener != null; 1271 break; 1272 case WindowEvent.WINDOW_STATE_CHANGED: 1273 enabled = ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0) 1274 || windowStateListener != null; 1275 break; 1276 default: 1277 enabled = super.eventTypeEnabled(type); 1278 } 1279 return enabled; 1280 } 1281 getUniqueLong()1282 private static synchronized long getUniqueLong() 1283 { 1284 return next_window_number++; 1285 } 1286 } 1287