1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing.plaf.basic; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import javax.swing.*; 31 import javax.swing.plaf.*; 32 import javax.swing.event.*; 33 import java.beans.*; 34 import sun.swing.DefaultLookup; 35 import sun.swing.UIAction; 36 37 /** 38 * A basic L&F implementation of JInternalFrame. 39 * 40 * @author David Kloba 41 * @author Rich Schiavi 42 */ 43 public class BasicInternalFrameUI extends InternalFrameUI 44 { 45 /** frame */ 46 protected JInternalFrame frame; 47 48 private Handler handler; 49 /** border listener */ 50 protected MouseInputAdapter borderListener; 51 /** property change listener */ 52 protected PropertyChangeListener propertyChangeListener; 53 /** internal frame layout */ 54 protected LayoutManager internalFrameLayout; 55 /** component listener */ 56 protected ComponentListener componentListener; 57 /** glass pane dispatcher */ 58 protected MouseInputListener glassPaneDispatcher; 59 private InternalFrameListener internalFrameListener; 60 61 /** north pane */ 62 protected JComponent northPane; 63 /** south pane */ 64 protected JComponent southPane; 65 /** west pane */ 66 protected JComponent westPane; 67 /** east pane */ 68 protected JComponent eastPane; 69 /** title pane */ 70 protected BasicInternalFrameTitlePane titlePane; // access needs this 71 72 private static DesktopManager sharedDesktopManager; 73 private boolean componentListenerAdded = false; 74 75 private Rectangle parentBounds; 76 77 private boolean dragging = false; 78 private boolean resizing = false; 79 80 /** 81 * As of Java 2 platform v1.3 this previously undocumented field is no 82 * longer used. 83 * Key bindings are now defined by the LookAndFeel, please refer to 84 * the key bindings specification for further details. 85 * 86 * @deprecated As of Java 2 platform v1.3. 87 */ 88 @Deprecated 89 protected KeyStroke openMenuKey; 90 91 private boolean keyBindingRegistered = false; 92 private boolean keyBindingActive = false; 93 94 ///////////////////////////////////////////////////////////////////////////// 95 // ComponentUI Interface Implementation methods 96 ///////////////////////////////////////////////////////////////////////////// 97 /** 98 * Returns a component UI. 99 * @param b a component 100 * @return a component UI 101 */ 102 public static ComponentUI createUI(JComponent b) { 103 return new BasicInternalFrameUI((JInternalFrame)b); 104 } 105 106 /** 107 * Constructs a {@code BasicInternalFrameUI}. 108 * @param b the internal frame 109 */ 110 public BasicInternalFrameUI(JInternalFrame b) { 111 LookAndFeel laf = UIManager.getLookAndFeel(); 112 if (laf instanceof BasicLookAndFeel) { 113 ((BasicLookAndFeel)laf).installAWTEventListener(); 114 } 115 } 116 117 /** 118 * Install the UI. 119 * @param c the component 120 */ 121 public void installUI(JComponent c) { 122 123 frame = (JInternalFrame)c; 124 125 installDefaults(); 126 installListeners(); 127 installComponents(); 128 installKeyboardActions(); 129 130 LookAndFeel.installProperty(frame, "opaque", Boolean.TRUE); 131 } 132 133 /** 134 * Uninstall the UI. 135 * @param c the component 136 */ 137 public void uninstallUI(JComponent c) { 138 if(c != frame) 139 throw new IllegalComponentStateException( 140 this + " was asked to deinstall() " 141 + c + " when it only knows about " 142 + frame + "."); 143 144 uninstallKeyboardActions(); 145 uninstallComponents(); 146 uninstallListeners(); 147 uninstallDefaults(); 148 updateFrameCursor(); 149 handler = null; 150 frame = null; 151 } 152 153 /** 154 * Install the defaults. 155 */ 156 protected void installDefaults(){ 157 Icon frameIcon = frame.getFrameIcon(); 158 if (frameIcon == null || frameIcon instanceof UIResource) { 159 frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon")); 160 } 161 162 // Enable the content pane to inherit background color from its 163 // parent by setting its background color to null. 164 Container contentPane = frame.getContentPane(); 165 if (contentPane != null) { 166 Color bg = contentPane.getBackground(); 167 if (bg instanceof UIResource) 168 contentPane.setBackground(null); 169 } 170 frame.setLayout(internalFrameLayout = createLayoutManager()); 171 frame.setBackground(UIManager.getLookAndFeelDefaults().getColor("control")); 172 173 LookAndFeel.installBorder(frame, "InternalFrame.border"); 174 175 } 176 /** 177 * Install the keyboard actions. 178 */ 179 protected void installKeyboardActions(){ 180 createInternalFrameListener(); 181 if (internalFrameListener != null) { 182 frame.addInternalFrameListener(internalFrameListener); 183 } 184 185 LazyActionMap.installLazyActionMap(frame, BasicInternalFrameUI.class, 186 "InternalFrame.actionMap"); 187 } 188 189 static void loadActionMap(LazyActionMap map) { 190 map.put(new UIAction("showSystemMenu") { 191 public void actionPerformed(ActionEvent evt) { 192 JInternalFrame iFrame = (JInternalFrame)evt.getSource(); 193 if (iFrame.getUI() instanceof BasicInternalFrameUI) { 194 JComponent comp = ((BasicInternalFrameUI) 195 iFrame.getUI()).getNorthPane(); 196 if (comp instanceof BasicInternalFrameTitlePane) { 197 ((BasicInternalFrameTitlePane)comp). 198 showSystemMenu(); 199 } 200 } 201 } 202 203 public boolean isEnabled(Object sender){ 204 if (sender instanceof JInternalFrame) { 205 JInternalFrame iFrame = (JInternalFrame)sender; 206 if (iFrame.getUI() instanceof BasicInternalFrameUI) { 207 return ((BasicInternalFrameUI)iFrame.getUI()). 208 isKeyBindingActive(); 209 } 210 } 211 return false; 212 } 213 }); 214 215 // Set the ActionMap's parent to the Auditory Feedback Action Map 216 BasicLookAndFeel.installAudioActionMap(map); 217 } 218 219 /** 220 * Installs the components. 221 */ 222 protected void installComponents(){ 223 setNorthPane(createNorthPane(frame)); 224 setSouthPane(createSouthPane(frame)); 225 setEastPane(createEastPane(frame)); 226 setWestPane(createWestPane(frame)); 227 } 228 229 /** 230 * Installs the listeners. 231 * @since 1.3 232 */ 233 protected void installListeners() { 234 borderListener = createBorderListener(frame); 235 propertyChangeListener = createPropertyChangeListener(); 236 frame.addPropertyChangeListener(propertyChangeListener); 237 installMouseHandlers(frame); 238 glassPaneDispatcher = createGlassPaneDispatcher(); 239 if (glassPaneDispatcher != null) { 240 frame.getGlassPane().addMouseListener(glassPaneDispatcher); 241 frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher); 242 } 243 componentListener = createComponentListener(); 244 if (frame.getParent() != null) { 245 parentBounds = frame.getParent().getBounds(); 246 } 247 if ((frame.getParent() != null) && !componentListenerAdded) { 248 frame.getParent().addComponentListener(componentListener); 249 componentListenerAdded = true; 250 } 251 } 252 253 // Provide a FocusListener to listen for a WINDOW_LOST_FOCUS event, 254 // so that a resize can be cancelled if the focus is lost while resizing 255 // when an Alt-Tab, modal dialog popup, iconify, dispose, or remove 256 // of the internal frame occurs. 257 private WindowFocusListener getWindowFocusListener(){ 258 return getHandler(); 259 } 260 261 // Cancel a resize in progress by calling finishMouseReleased(). 262 private void cancelResize() { 263 if (resizing) { 264 if (borderListener instanceof BorderListener) { 265 ((BorderListener)borderListener).finishMouseReleased(); 266 } 267 } 268 } 269 270 private Handler getHandler() { 271 if (handler == null) { 272 handler = new Handler(); 273 } 274 return handler; 275 } 276 277 InputMap getInputMap(int condition) { 278 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) { 279 return createInputMap(condition); 280 } 281 return null; 282 } 283 284 InputMap createInputMap(int condition) { 285 if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) { 286 Object[] bindings = (Object[])DefaultLookup.get( 287 frame, this, "InternalFrame.windowBindings"); 288 289 if (bindings != null) { 290 return LookAndFeel.makeComponentInputMap(frame, bindings); 291 } 292 } 293 return null; 294 } 295 296 /** 297 * Uninstall the defaults. 298 */ 299 protected void uninstallDefaults() { 300 Icon frameIcon = frame.getFrameIcon(); 301 if (frameIcon instanceof UIResource) { 302 frame.setFrameIcon(null); 303 } 304 internalFrameLayout = null; 305 frame.setLayout(null); 306 LookAndFeel.uninstallBorder(frame); 307 } 308 309 /** 310 * Uninstall the components. 311 */ 312 protected void uninstallComponents(){ 313 setNorthPane(null); 314 setSouthPane(null); 315 setEastPane(null); 316 setWestPane(null); 317 if(titlePane != null) { 318 titlePane.uninstallDefaults(); 319 } 320 titlePane = null; 321 } 322 323 /** 324 * Uninstall the listeners. 325 * @since 1.3 326 */ 327 protected void uninstallListeners() { 328 if ((frame.getParent() != null) && componentListenerAdded) { 329 frame.getParent().removeComponentListener(componentListener); 330 componentListenerAdded = false; 331 } 332 componentListener = null; 333 if (glassPaneDispatcher != null) { 334 frame.getGlassPane().removeMouseListener(glassPaneDispatcher); 335 frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher); 336 glassPaneDispatcher = null; 337 } 338 deinstallMouseHandlers(frame); 339 frame.removePropertyChangeListener(propertyChangeListener); 340 propertyChangeListener = null; 341 borderListener = null; 342 } 343 344 /** 345 * Uninstall the keyboard actions. 346 */ 347 protected void uninstallKeyboardActions(){ 348 if (internalFrameListener != null) { 349 frame.removeInternalFrameListener(internalFrameListener); 350 } 351 internalFrameListener = null; 352 353 SwingUtilities.replaceUIInputMap(frame, JComponent. 354 WHEN_IN_FOCUSED_WINDOW, null); 355 SwingUtilities.replaceUIActionMap(frame, null); 356 357 } 358 359 void updateFrameCursor() { 360 if (resizing) { 361 return; 362 } 363 Cursor s = frame.getLastCursor(); 364 if (s == null) { 365 s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 366 } 367 frame.setCursor(s); 368 } 369 370 /** 371 * Creates the layout manager. 372 * @return the layout manager 373 */ 374 protected LayoutManager createLayoutManager(){ 375 return getHandler(); 376 } 377 378 /** 379 * Creates the property change listener. 380 * @return the property change listener 381 */ 382 protected PropertyChangeListener createPropertyChangeListener(){ 383 return getHandler(); 384 } 385 386 /** 387 * Returns the preferred size. 388 * @param x the component 389 * @return the preferred size 390 */ 391 public Dimension getPreferredSize(JComponent x) { 392 if(frame == x) 393 return frame.getLayout().preferredLayoutSize(x); 394 return new Dimension(100, 100); 395 } 396 397 /** 398 * Returns the minimum size. 399 * @param x the component 400 * @return the minimum size 401 */ 402 public Dimension getMinimumSize(JComponent x) { 403 if(frame == x) { 404 return frame.getLayout().minimumLayoutSize(x); 405 } 406 return new Dimension(0, 0); 407 } 408 409 /** 410 * Returns the maximum size. 411 * @param x the component 412 * @return the maximum size 413 */ 414 public Dimension getMaximumSize(JComponent x) { 415 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 416 } 417 418 419 420 /** 421 * Installs necessary mouse handlers on <code>newPane</code> 422 * and adds it to the frame. 423 * Reverse process for the <code>currentPane</code>. 424 * 425 * @param currentPane this {@code Jcomponent} is the current pane being 426 * viewed that has mouse handlers installed 427 * @param newPane this {@code Jcomponent} is the pane which will be added 428 * and have mouse handlers installed 429 */ 430 protected void replacePane(JComponent currentPane, JComponent newPane) { 431 if(currentPane != null) { 432 deinstallMouseHandlers(currentPane); 433 frame.remove(currentPane); 434 } 435 if(newPane != null) { 436 frame.add(newPane); 437 installMouseHandlers(newPane); 438 } 439 } 440 441 /** 442 * Deinstalls the mouse handlers. 443 * @param c the component 444 */ 445 protected void deinstallMouseHandlers(JComponent c) { 446 c.removeMouseListener(borderListener); 447 c.removeMouseMotionListener(borderListener); 448 } 449 450 /** 451 * Installs the mouse handlers. 452 * @param c the component 453 */ 454 protected void installMouseHandlers(JComponent c) { 455 c.addMouseListener(borderListener); 456 c.addMouseMotionListener(borderListener); 457 } 458 459 /** 460 * Creates the north pane. 461 * @param w the internal frame 462 * @return the north pane 463 */ 464 protected JComponent createNorthPane(JInternalFrame w) { 465 titlePane = new BasicInternalFrameTitlePane(w); 466 return titlePane; 467 } 468 469 470 /** 471 * Creates the north pane. 472 * @param w the internal frame 473 * @return the north pane 474 */ 475 protected JComponent createSouthPane(JInternalFrame w) { 476 return null; 477 } 478 479 /** 480 * Creates the west pane. 481 * @param w the internal frame 482 * @return the west pane 483 */ 484 protected JComponent createWestPane(JInternalFrame w) { 485 return null; 486 } 487 488 /** 489 * Creates the east pane. 490 * @param w the internal frame 491 * @return the east pane 492 */ 493 protected JComponent createEastPane(JInternalFrame w) { 494 return null; 495 } 496 497 /** 498 * Creates the border listener. 499 * @param w the internal frame 500 * @return the border listener 501 */ 502 protected MouseInputAdapter createBorderListener(JInternalFrame w) { 503 return new BorderListener(); 504 } 505 506 /** 507 * Creates the internal frame listener. 508 */ 509 protected void createInternalFrameListener(){ 510 internalFrameListener = getHandler(); 511 } 512 513 /** 514 * Returns whether or no the key binding is registered. 515 * @return whether or no the key binding is registered 516 */ 517 protected final boolean isKeyBindingRegistered(){ 518 return keyBindingRegistered; 519 } 520 521 /** 522 * Sets the key binding registration. 523 * @param b new value for key binding registration 524 */ 525 protected final void setKeyBindingRegistered(boolean b){ 526 keyBindingRegistered = b; 527 } 528 529 /** 530 * Returns whether or no the key binding is active. 531 * @return whether or no the key binding is active 532 */ 533 public final boolean isKeyBindingActive(){ 534 return keyBindingActive; 535 } 536 537 /** 538 * Sets the key binding activity. 539 * @param b new value for key binding activity 540 */ 541 protected final void setKeyBindingActive(boolean b){ 542 keyBindingActive = b; 543 } 544 545 546 /** 547 * Setup the menu open key. 548 */ 549 protected void setupMenuOpenKey(){ 550 // PENDING(hania): Why are these WHEN_IN_FOCUSED_WINDOWs? Shouldn't 551 // they be WHEN_ANCESTOR_OF_FOCUSED_COMPONENT? 552 // Also, no longer registering on the desktopicon, the previous 553 // action did nothing. 554 InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 555 SwingUtilities.replaceUIInputMap(frame, 556 JComponent.WHEN_IN_FOCUSED_WINDOW, map); 557 //ActionMap actionMap = getActionMap(); 558 //SwingUtilities.replaceUIActionMap(frame, actionMap); 559 } 560 561 /** 562 * Setup the menu close key. 563 */ 564 protected void setupMenuCloseKey(){ 565 } 566 567 /** 568 * Returns the north pane. 569 * @return the north pane 570 */ 571 public JComponent getNorthPane() { 572 return northPane; 573 } 574 575 /** 576 * Set the north pane. 577 * @param c the new north pane 578 */ 579 public void setNorthPane(JComponent c) { 580 if (northPane != null && 581 northPane instanceof BasicInternalFrameTitlePane) { 582 ((BasicInternalFrameTitlePane)northPane).uninstallListeners(); 583 } 584 replacePane(northPane, c); 585 northPane = c; 586 if (c instanceof BasicInternalFrameTitlePane) { 587 titlePane = (BasicInternalFrameTitlePane)c; 588 } 589 } 590 591 /** 592 * Returns the south pane. 593 * @return the south pane 594 */ 595 public JComponent getSouthPane() { 596 return southPane; 597 } 598 599 /** 600 * Set the south pane. 601 * @param c the new south pane 602 */ 603 public void setSouthPane(JComponent c) { 604 southPane = c; 605 } 606 607 /** 608 * Returns the west pane. 609 * @return the west pane 610 */ 611 public JComponent getWestPane() { 612 return westPane; 613 } 614 615 /** 616 * Set the west pane. 617 * @param c the new west pane 618 */ 619 public void setWestPane(JComponent c) { 620 westPane = c; 621 } 622 623 /** 624 * Returns the east pane. 625 * @return the east pane 626 */ 627 public JComponent getEastPane() { 628 return eastPane; 629 } 630 631 /** 632 * Set the east pane. 633 * @param c the new east pane 634 */ 635 public void setEastPane(JComponent c) { 636 eastPane = c; 637 } 638 639 /** 640 * Internal frame property change listener. 641 */ 642 public class InternalFramePropertyChangeListener implements 643 PropertyChangeListener { 644 // NOTE: This class exists only for backward compatibility. All 645 // its functionality has been moved into Handler. If you need to add 646 // new functionality add it to the Handler, but make sure this 647 // class calls into the Handler. 648 /** 649 * Detects changes in state from the JInternalFrame and handles 650 * actions. 651 */ 652 public void propertyChange(PropertyChangeEvent evt) { 653 getHandler().propertyChange(evt); 654 } 655 } 656 657 /** 658 * Internal frame layout. 659 */ 660 public class InternalFrameLayout implements LayoutManager { 661 // NOTE: This class exists only for backward compatibility. All 662 // its functionality has been moved into Handler. If you need to add 663 // new functionality add it to the Handler, but make sure this 664 // class calls into the Handler. 665 /** 666 * {@inheritDoc} 667 */ 668 public void addLayoutComponent(String name, Component c) { 669 getHandler().addLayoutComponent(name, c); 670 } 671 672 /** 673 * {@inheritDoc} 674 */ 675 public void removeLayoutComponent(Component c) { 676 getHandler().removeLayoutComponent(c); 677 } 678 679 /** 680 * {@inheritDoc} 681 */ 682 public Dimension preferredLayoutSize(Container c) { 683 return getHandler().preferredLayoutSize(c); 684 } 685 686 /** 687 * {@inheritDoc} 688 */ 689 public Dimension minimumLayoutSize(Container c) { 690 return getHandler().minimumLayoutSize(c); 691 } 692 693 /** 694 * {@inheritDoc} 695 */ 696 public void layoutContainer(Container c) { 697 getHandler().layoutContainer(c); 698 } 699 } 700 701 /// DesktopManager methods 702 /** 703 * Returns the proper DesktopManager. Calls getDesktopPane() to 704 * find the JDesktop component and returns the desktopManager from 705 * it. If this fails, it will return a default DesktopManager that 706 * should work in arbitrary parents. 707 * @return the proper DesktopManager 708 */ 709 protected DesktopManager getDesktopManager() { 710 if(frame.getDesktopPane() != null 711 && frame.getDesktopPane().getDesktopManager() != null) 712 return frame.getDesktopPane().getDesktopManager(); 713 if(sharedDesktopManager == null) 714 sharedDesktopManager = createDesktopManager(); 715 return sharedDesktopManager; 716 } 717 718 /** 719 * Creates the desktop manager. 720 * @return the desktop manager 721 */ 722 protected DesktopManager createDesktopManager(){ 723 return new DefaultDesktopManager(); 724 } 725 726 /** 727 * This method is called when the user wants to close the frame. 728 * The <code>playCloseSound</code> Action is fired. 729 * This action is delegated to the desktopManager. 730 * 731 * @param f the {@code JInternalFrame} being viewed 732 */ 733 protected void closeFrame(JInternalFrame f) { 734 // Internal Frame Auditory Cue Activation 735 BasicLookAndFeel.playSound(frame,"InternalFrame.closeSound"); 736 // delegate to desktop manager 737 getDesktopManager().closeFrame(f); 738 } 739 740 /** 741 * This method is called when the user wants to maximize the frame. 742 * The <code>playMaximizeSound</code> Action is fired. 743 * This action is delegated to the desktopManager. 744 * 745 * @param f the {@code JInternalFrame} being viewed 746 */ 747 protected void maximizeFrame(JInternalFrame f) { 748 // Internal Frame Auditory Cue Activation 749 BasicLookAndFeel.playSound(frame,"InternalFrame.maximizeSound"); 750 // delegate to desktop manager 751 getDesktopManager().maximizeFrame(f); 752 } 753 754 /** 755 * This method is called when the user wants to minimize the frame. 756 * The <code>playRestoreDownSound</code> Action is fired. 757 * This action is delegated to the desktopManager. 758 * 759 * @param f the {@code JInternalFrame} being viewed 760 */ 761 protected void minimizeFrame(JInternalFrame f) { 762 // Internal Frame Auditory Cue Activation 763 if ( ! f.isIcon() ) { 764 // This method seems to regularly get called after an 765 // internal frame is iconified. Don't play this sound then. 766 BasicLookAndFeel.playSound(frame,"InternalFrame.restoreDownSound"); 767 } 768 // delegate to desktop manager 769 getDesktopManager().minimizeFrame(f); 770 } 771 772 /** 773 * This method is called when the user wants to iconify the frame. 774 * The <code>playMinimizeSound</code> Action is fired. 775 * This action is delegated to the desktopManager. 776 * 777 * @param f the {@code JInternalFrame} being viewed 778 */ 779 protected void iconifyFrame(JInternalFrame f) { 780 // Internal Frame Auditory Cue Activation 781 BasicLookAndFeel.playSound(frame, "InternalFrame.minimizeSound"); 782 // delegate to desktop manager 783 getDesktopManager().iconifyFrame(f); 784 } 785 786 /** 787 * This method is called when the user wants to deiconify the frame. 788 * The <code>playRestoreUpSound</code> Action is fired. 789 * This action is delegated to the desktopManager. 790 * 791 * @param f the {@code JInternalFrame} being viewed 792 */ 793 protected void deiconifyFrame(JInternalFrame f) { 794 // Internal Frame Auditory Cue Activation 795 if ( ! f.isMaximum() ) { 796 // This method seems to regularly get called after an 797 // internal frame is maximized. Don't play this sound then. 798 BasicLookAndFeel.playSound(frame, "InternalFrame.restoreUpSound"); 799 } 800 // delegate to desktop manager 801 getDesktopManager().deiconifyFrame(f); 802 } 803 804 /** 805 * This method is called when the frame becomes selected. 806 * This action is delegated to the desktopManager. 807 * 808 * @param f the {@code JInternalFrame} being viewed 809 */ 810 protected void activateFrame(JInternalFrame f) { 811 getDesktopManager().activateFrame(f); 812 } 813 /** 814 * This method is called when the frame is no longer selected. 815 * This action is delegated to the desktopManager. 816 * 817 * @param f the {@code JInternalFrame} being viewed 818 */ 819 protected void deactivateFrame(JInternalFrame f) { 820 getDesktopManager().deactivateFrame(f); 821 } 822 823 ///////////////////////////////////////////////////////////////////////// 824 /// Border Listener Class 825 ///////////////////////////////////////////////////////////////////////// 826 /** 827 * Listens for border adjustments. 828 */ 829 protected class BorderListener extends MouseInputAdapter implements SwingConstants 830 { 831 // _x & _y are the mousePressed location in absolute coordinate system 832 int _x, _y; 833 // __x & __y are the mousePressed location in source view's coordinate system 834 int __x, __y; 835 Rectangle startingBounds; 836 int resizeDir; 837 838 /** resize none */ 839 protected final int RESIZE_NONE = 0; 840 private boolean discardRelease = false; 841 842 int resizeCornerSize = 16; 843 844 public void mouseClicked(MouseEvent e) { 845 if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) { 846 if(frame.isIconifiable() && frame.isIcon()) { 847 try { frame.setIcon(false); } catch (PropertyVetoException e2) { } 848 } else if(frame.isMaximizable()) { 849 if(!frame.isMaximum()) 850 try { frame.setMaximum(true); } catch (PropertyVetoException e2) { } 851 else 852 try { frame.setMaximum(false); } catch (PropertyVetoException e3) { } 853 } 854 } 855 } 856 857 // Factor out finishMouseReleased() from mouseReleased(), so that 858 // it can be called by cancelResize() without passing it a null 859 // MouseEvent. 860 void finishMouseReleased() { 861 if (discardRelease) { 862 discardRelease = false; 863 return; 864 } 865 if (resizeDir == RESIZE_NONE) { 866 getDesktopManager().endDraggingFrame(frame); 867 dragging = false; 868 } else { 869 // Remove the WindowFocusListener for handling a 870 // WINDOW_LOST_FOCUS event with a cancelResize(). 871 Window windowAncestor = 872 SwingUtilities.getWindowAncestor(frame); 873 if (windowAncestor != null) { 874 windowAncestor.removeWindowFocusListener( 875 getWindowFocusListener()); 876 } 877 Container c = frame.getTopLevelAncestor(); 878 if (c instanceof RootPaneContainer) { 879 Component glassPane = ((RootPaneContainer)c).getGlassPane(); 880 glassPane.setCursor(Cursor.getPredefinedCursor( 881 Cursor.DEFAULT_CURSOR)); 882 glassPane.setVisible(false); 883 } 884 getDesktopManager().endResizingFrame(frame); 885 resizing = false; 886 updateFrameCursor(); 887 } 888 _x = 0; 889 _y = 0; 890 __x = 0; 891 __y = 0; 892 startingBounds = null; 893 resizeDir = RESIZE_NONE; 894 // Set discardRelease to true, so that only a mousePressed() 895 // which sets it to false, will allow entry to the above code 896 // for finishing a resize. 897 discardRelease = true; 898 } 899 900 public void mouseReleased(MouseEvent e) { 901 finishMouseReleased(); 902 } 903 904 public void mousePressed(MouseEvent e) { 905 Point p = SwingUtilities.convertPoint((Component)e.getSource(), 906 e.getX(), e.getY(), null); 907 __x = e.getX(); 908 __y = e.getY(); 909 _x = p.x; 910 _y = p.y; 911 startingBounds = frame.getBounds(); 912 resizeDir = RESIZE_NONE; 913 discardRelease = false; 914 915 try { frame.setSelected(true); } 916 catch (PropertyVetoException e1) { } 917 918 Insets i = frame.getInsets(); 919 920 Point ep = new Point(__x, __y); 921 if (e.getSource() == getNorthPane()) { 922 Point np = getNorthPane().getLocation(); 923 ep.x += np.x; 924 ep.y += np.y; 925 } 926 927 if (e.getSource() == getNorthPane()) { 928 if (ep.x > i.left && ep.y > i.top && ep.x < frame.getWidth() - i.right) { 929 getDesktopManager().beginDraggingFrame(frame); 930 dragging = true; 931 return; 932 } 933 } 934 if (!frame.isResizable()) { 935 return; 936 } 937 938 if (e.getSource() == frame || e.getSource() == getNorthPane()) { 939 if (ep.x <= i.left) { 940 if (ep.y < resizeCornerSize + i.top) { 941 resizeDir = NORTH_WEST; 942 } else if (ep.y > frame.getHeight() 943 - resizeCornerSize - i.bottom) { 944 resizeDir = SOUTH_WEST; 945 } else { 946 resizeDir = WEST; 947 } 948 } else if (ep.x >= frame.getWidth() - i.right) { 949 if (ep.y < resizeCornerSize + i.top) { 950 resizeDir = NORTH_EAST; 951 } else if (ep.y > frame.getHeight() 952 - resizeCornerSize - i.bottom) { 953 resizeDir = SOUTH_EAST; 954 } else { 955 resizeDir = EAST; 956 } 957 } else if (ep.y <= i.top) { 958 if (ep.x < resizeCornerSize + i.left) { 959 resizeDir = NORTH_WEST; 960 } else if (ep.x > frame.getWidth() 961 - resizeCornerSize - i.right) { 962 resizeDir = NORTH_EAST; 963 } else { 964 resizeDir = NORTH; 965 } 966 } else if (ep.y >= frame.getHeight() - i.bottom) { 967 if (ep.x < resizeCornerSize + i.left) { 968 resizeDir = SOUTH_WEST; 969 } else if (ep.x > frame.getWidth() 970 - resizeCornerSize - i.right) { 971 resizeDir = SOUTH_EAST; 972 } else { 973 resizeDir = SOUTH; 974 } 975 } else { 976 /* the mouse press happened inside the frame, not in the 977 border */ 978 discardRelease = true; 979 return; 980 } 981 Cursor s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 982 switch (resizeDir) { 983 case SOUTH: 984 s = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR); 985 break; 986 case NORTH: 987 s = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR); 988 break; 989 case WEST: 990 s = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); 991 break; 992 case EAST: 993 s = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); 994 break; 995 case SOUTH_EAST: 996 s = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR); 997 break; 998 case SOUTH_WEST: 999 s = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR); 1000 break; 1001 case NORTH_WEST: 1002 s = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR); 1003 break; 1004 case NORTH_EAST: 1005 s = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR); 1006 break; 1007 } 1008 Container c = frame.getTopLevelAncestor(); 1009 if (c instanceof RootPaneContainer) { 1010 Component glassPane = ((RootPaneContainer)c).getGlassPane(); 1011 glassPane.setVisible(true); 1012 glassPane.setCursor(s); 1013 } 1014 getDesktopManager().beginResizingFrame(frame, resizeDir); 1015 resizing = true; 1016 // Add the WindowFocusListener for handling a 1017 // WINDOW_LOST_FOCUS event with a cancelResize(). 1018 Window windowAncestor = SwingUtilities.getWindowAncestor(frame); 1019 if (windowAncestor != null) { 1020 windowAncestor.addWindowFocusListener( 1021 getWindowFocusListener()); 1022 } 1023 return; 1024 } 1025 } 1026 1027 public void mouseDragged(MouseEvent e) { 1028 1029 if ( startingBounds == null ) { 1030 // (STEVE) Yucky work around for bug ID 4106552 1031 return; 1032 } 1033 1034 Point p = SwingUtilities.convertPoint((Component)e.getSource(), 1035 e.getX(), e.getY(), null); 1036 int deltaX = _x - p.x; 1037 int deltaY = _y - p.y; 1038 Dimension min = frame.getMinimumSize(); 1039 Dimension max = frame.getMaximumSize(); 1040 int newX, newY, newW, newH; 1041 Insets i = frame.getInsets(); 1042 1043 // Handle a MOVE 1044 if (dragging) { 1045 if (frame.isMaximum() || ((e.getModifiers() & 1046 InputEvent.BUTTON1_MASK) != 1047 InputEvent.BUTTON1_MASK)) { 1048 // don't allow moving of frames if maximixed or left mouse 1049 // button was not used. 1050 return; 1051 } 1052 int pWidth, pHeight; 1053 Dimension s = frame.getParent().getSize(); 1054 pWidth = s.width; 1055 pHeight = s.height; 1056 1057 1058 newX = startingBounds.x - deltaX; 1059 newY = startingBounds.y - deltaY; 1060 1061 // Make sure we stay in-bounds 1062 if(newX + i.left <= -__x) 1063 newX = -__x - i.left + 1; 1064 if(newY + i.top <= -__y) 1065 newY = -__y - i.top + 1; 1066 if(newX + __x + i.right >= pWidth) 1067 newX = pWidth - __x - i.right - 1; 1068 if(newY + __y + i.bottom >= pHeight) 1069 newY = pHeight - __y - i.bottom - 1; 1070 1071 getDesktopManager().dragFrame(frame, newX, newY); 1072 return; 1073 } 1074 1075 if(!frame.isResizable()) { 1076 return; 1077 } 1078 1079 newX = frame.getX(); 1080 newY = frame.getY(); 1081 newW = frame.getWidth(); 1082 newH = frame.getHeight(); 1083 1084 parentBounds = frame.getParent().getBounds(); 1085 1086 switch(resizeDir) { 1087 case RESIZE_NONE: 1088 return; 1089 case NORTH: 1090 if(startingBounds.height + deltaY < min.height) 1091 deltaY = -(startingBounds.height - min.height); 1092 else if(startingBounds.height + deltaY > max.height) 1093 deltaY = max.height - startingBounds.height; 1094 if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;} 1095 1096 newX = startingBounds.x; 1097 newY = startingBounds.y - deltaY; 1098 newW = startingBounds.width; 1099 newH = startingBounds.height + deltaY; 1100 break; 1101 case NORTH_EAST: 1102 if(startingBounds.height + deltaY < min.height) 1103 deltaY = -(startingBounds.height - min.height); 1104 else if(startingBounds.height + deltaY > max.height) 1105 deltaY = max.height - startingBounds.height; 1106 if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;} 1107 1108 if(startingBounds.width - deltaX < min.width) 1109 deltaX = startingBounds.width - min.width; 1110 else if(startingBounds.width - deltaX > max.width) 1111 deltaX = -(max.width - startingBounds.width); 1112 if (startingBounds.x + startingBounds.width - deltaX > 1113 parentBounds.width) { 1114 deltaX = startingBounds.x + startingBounds.width - 1115 parentBounds.width; 1116 } 1117 1118 newX = startingBounds.x; 1119 newY = startingBounds.y - deltaY; 1120 newW = startingBounds.width - deltaX; 1121 newH = startingBounds.height + deltaY; 1122 break; 1123 case EAST: 1124 if(startingBounds.width - deltaX < min.width) 1125 deltaX = startingBounds.width - min.width; 1126 else if(startingBounds.width - deltaX > max.width) 1127 deltaX = -(max.width - startingBounds.width); 1128 if (startingBounds.x + startingBounds.width - deltaX > 1129 parentBounds.width) { 1130 deltaX = startingBounds.x + startingBounds.width - 1131 parentBounds.width; 1132 } 1133 1134 newW = startingBounds.width - deltaX; 1135 newH = startingBounds.height; 1136 break; 1137 case SOUTH_EAST: 1138 if(startingBounds.width - deltaX < min.width) 1139 deltaX = startingBounds.width - min.width; 1140 else if(startingBounds.width - deltaX > max.width) 1141 deltaX = -(max.width - startingBounds.width); 1142 if (startingBounds.x + startingBounds.width - deltaX > 1143 parentBounds.width) { 1144 deltaX = startingBounds.x + startingBounds.width - 1145 parentBounds.width; 1146 } 1147 1148 if(startingBounds.height - deltaY < min.height) 1149 deltaY = startingBounds.height - min.height; 1150 else if(startingBounds.height - deltaY > max.height) 1151 deltaY = -(max.height - startingBounds.height); 1152 if (startingBounds.y + startingBounds.height - deltaY > 1153 parentBounds.height) { 1154 deltaY = startingBounds.y + startingBounds.height - 1155 parentBounds.height ; 1156 } 1157 1158 newW = startingBounds.width - deltaX; 1159 newH = startingBounds.height - deltaY; 1160 break; 1161 case SOUTH: 1162 if(startingBounds.height - deltaY < min.height) 1163 deltaY = startingBounds.height - min.height; 1164 else if(startingBounds.height - deltaY > max.height) 1165 deltaY = -(max.height - startingBounds.height); 1166 if (startingBounds.y + startingBounds.height - deltaY > 1167 parentBounds.height) { 1168 deltaY = startingBounds.y + startingBounds.height - 1169 parentBounds.height ; 1170 } 1171 1172 newW = startingBounds.width; 1173 newH = startingBounds.height - deltaY; 1174 break; 1175 case SOUTH_WEST: 1176 if(startingBounds.height - deltaY < min.height) 1177 deltaY = startingBounds.height - min.height; 1178 else if(startingBounds.height - deltaY > max.height) 1179 deltaY = -(max.height - startingBounds.height); 1180 if (startingBounds.y + startingBounds.height - deltaY > 1181 parentBounds.height) { 1182 deltaY = startingBounds.y + startingBounds.height - 1183 parentBounds.height ; 1184 } 1185 1186 if(startingBounds.width + deltaX < min.width) 1187 deltaX = -(startingBounds.width - min.width); 1188 else if(startingBounds.width + deltaX > max.width) 1189 deltaX = max.width - startingBounds.width; 1190 if (startingBounds.x - deltaX < 0) { 1191 deltaX = startingBounds.x; 1192 } 1193 1194 newX = startingBounds.x - deltaX; 1195 newY = startingBounds.y; 1196 newW = startingBounds.width + deltaX; 1197 newH = startingBounds.height - deltaY; 1198 break; 1199 case WEST: 1200 if(startingBounds.width + deltaX < min.width) 1201 deltaX = -(startingBounds.width - min.width); 1202 else if(startingBounds.width + deltaX > max.width) 1203 deltaX = max.width - startingBounds.width; 1204 if (startingBounds.x - deltaX < 0) { 1205 deltaX = startingBounds.x; 1206 } 1207 1208 newX = startingBounds.x - deltaX; 1209 newY = startingBounds.y; 1210 newW = startingBounds.width + deltaX; 1211 newH = startingBounds.height; 1212 break; 1213 case NORTH_WEST: 1214 if(startingBounds.width + deltaX < min.width) 1215 deltaX = -(startingBounds.width - min.width); 1216 else if(startingBounds.width + deltaX > max.width) 1217 deltaX = max.width - startingBounds.width; 1218 if (startingBounds.x - deltaX < 0) { 1219 deltaX = startingBounds.x; 1220 } 1221 1222 if(startingBounds.height + deltaY < min.height) 1223 deltaY = -(startingBounds.height - min.height); 1224 else if(startingBounds.height + deltaY > max.height) 1225 deltaY = max.height - startingBounds.height; 1226 if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;} 1227 1228 newX = startingBounds.x - deltaX; 1229 newY = startingBounds.y - deltaY; 1230 newW = startingBounds.width + deltaX; 1231 newH = startingBounds.height + deltaY; 1232 break; 1233 default: 1234 return; 1235 } 1236 getDesktopManager().resizeFrame(frame, newX, newY, newW, newH); 1237 } 1238 1239 public void mouseMoved(MouseEvent e) { 1240 1241 if(!frame.isResizable()) 1242 return; 1243 1244 if (e.getSource() == frame || e.getSource() == getNorthPane()) { 1245 Insets i = frame.getInsets(); 1246 Point ep = new Point(e.getX(), e.getY()); 1247 if (e.getSource() == getNorthPane()) { 1248 Point np = getNorthPane().getLocation(); 1249 ep.x += np.x; 1250 ep.y += np.y; 1251 } 1252 if(ep.x <= i.left) { 1253 if(ep.y < resizeCornerSize + i.top) 1254 frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)); 1255 else if(ep.y > frame.getHeight() - resizeCornerSize - i.bottom) 1256 frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR)); 1257 else 1258 frame.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); 1259 } else if(ep.x >= frame.getWidth() - i.right) { 1260 if(e.getY() < resizeCornerSize + i.top) 1261 frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)); 1262 else if(ep.y > frame.getHeight() - resizeCornerSize - i.bottom) 1263 frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)); 1264 else 1265 frame.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); 1266 } else if(ep.y <= i.top) { 1267 if(ep.x < resizeCornerSize + i.left) 1268 frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)); 1269 else if(ep.x > frame.getWidth() - resizeCornerSize - i.right) 1270 frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)); 1271 else 1272 frame.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); 1273 } else if(ep.y >= frame.getHeight() - i.bottom) { 1274 if(ep.x < resizeCornerSize + i.left) 1275 frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR)); 1276 else if(ep.x > frame.getWidth() - resizeCornerSize - i.right) 1277 frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)); 1278 else 1279 frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); 1280 } 1281 else 1282 updateFrameCursor(); 1283 return; 1284 } 1285 1286 updateFrameCursor(); 1287 } 1288 1289 public void mouseEntered(MouseEvent e) { 1290 updateFrameCursor(); 1291 } 1292 1293 public void mouseExited(MouseEvent e) { 1294 updateFrameCursor(); 1295 } 1296 1297 } /// End BorderListener Class 1298 1299 /** 1300 * Component handler. 1301 */ 1302 protected class ComponentHandler implements ComponentListener { 1303 // NOTE: This class exists only for backward compatibility. All 1304 // its functionality has been moved into Handler. If you need to add 1305 // new functionality add it to the Handler, but make sure this 1306 // class calls into the Handler. 1307 /** Invoked when a JInternalFrame's parent's size changes. */ 1308 public void componentResized(ComponentEvent e) { 1309 getHandler().componentResized(e); 1310 } 1311 1312 /** 1313 * {@inheritDoc} 1314 */ 1315 public void componentMoved(ComponentEvent e) { 1316 getHandler().componentMoved(e); 1317 } 1318 /** 1319 * {@inheritDoc} 1320 */ 1321 public void componentShown(ComponentEvent e) { 1322 getHandler().componentShown(e); 1323 } 1324 /** 1325 * {@inheritDoc} 1326 */ 1327 public void componentHidden(ComponentEvent e) { 1328 getHandler().componentHidden(e); 1329 } 1330 } 1331 1332 /** 1333 * Creates a component listener. 1334 * @return a component listener 1335 */ 1336 protected ComponentListener createComponentListener() { 1337 return getHandler(); 1338 } 1339 1340 1341 /** 1342 * Glass pane dispatcher. 1343 */ 1344 protected class GlassPaneDispatcher implements MouseInputListener { 1345 // NOTE: This class exists only for backward compatibility. All 1346 // its functionality has been moved into Handler. If you need to add 1347 // new functionality add it to the Handler, but make sure this 1348 // class calls into the Handler. 1349 /** 1350 * {@inheritDoc} 1351 */ 1352 public void mousePressed(MouseEvent e) { 1353 getHandler().mousePressed(e); 1354 } 1355 1356 /** 1357 * {@inheritDoc} 1358 */ 1359 public void mouseEntered(MouseEvent e) { 1360 getHandler().mouseEntered(e); 1361 } 1362 1363 /** 1364 * {@inheritDoc} 1365 */ 1366 public void mouseMoved(MouseEvent e) { 1367 getHandler().mouseMoved(e); 1368 } 1369 1370 /** 1371 * {@inheritDoc} 1372 */ 1373 public void mouseExited(MouseEvent e) { 1374 getHandler().mouseExited(e); 1375 } 1376 1377 /** 1378 * {@inheritDoc} 1379 */ 1380 public void mouseClicked(MouseEvent e) { 1381 getHandler().mouseClicked(e); 1382 } 1383 1384 /** 1385 * {@inheritDoc} 1386 */ 1387 public void mouseReleased(MouseEvent e) { 1388 getHandler().mouseReleased(e); 1389 } 1390 1391 /** 1392 * {@inheritDoc} 1393 */ 1394 public void mouseDragged(MouseEvent e) { 1395 getHandler().mouseDragged(e); 1396 } 1397 } 1398 1399 /** 1400 * Creates a {@code GlassPaneDispatcher}. 1401 * @return a {@code GlassPaneDispatcher} 1402 */ 1403 protected MouseInputListener createGlassPaneDispatcher() { 1404 return null; 1405 } 1406 1407 /** 1408 * Basic internal frame listener. 1409 */ 1410 protected class BasicInternalFrameListener implements InternalFrameListener 1411 { 1412 // NOTE: This class exists only for backward compatibility. All 1413 // its functionality has been moved into Handler. If you need to add 1414 // new functionality add it to the Handler, but make sure this 1415 // class calls into the Handler. 1416 /** 1417 * {@inheritDoc} 1418 */ 1419 public void internalFrameClosing(InternalFrameEvent e) { 1420 getHandler().internalFrameClosing(e); 1421 } 1422 1423 /** 1424 * {@inheritDoc} 1425 */ 1426 public void internalFrameClosed(InternalFrameEvent e) { 1427 getHandler().internalFrameClosed(e); 1428 } 1429 1430 /** 1431 * {@inheritDoc} 1432 */ 1433 public void internalFrameOpened(InternalFrameEvent e) { 1434 getHandler().internalFrameOpened(e); 1435 } 1436 1437 /** 1438 * {@inheritDoc} 1439 */ 1440 public void internalFrameIconified(InternalFrameEvent e) { 1441 getHandler().internalFrameIconified(e); 1442 } 1443 1444 /** 1445 * {@inheritDoc} 1446 */ 1447 public void internalFrameDeiconified(InternalFrameEvent e) { 1448 getHandler().internalFrameDeiconified(e); 1449 } 1450 1451 /** 1452 * {@inheritDoc} 1453 */ 1454 public void internalFrameActivated(InternalFrameEvent e) { 1455 getHandler().internalFrameActivated(e); 1456 } 1457 1458 /** 1459 * {@inheritDoc} 1460 */ 1461 public void internalFrameDeactivated(InternalFrameEvent e) { 1462 getHandler().internalFrameDeactivated(e); 1463 } 1464 } 1465 1466 private class Handler implements ComponentListener, InternalFrameListener, 1467 LayoutManager, MouseInputListener, PropertyChangeListener, 1468 WindowFocusListener, SwingConstants { 1469 1470 public void windowGainedFocus(WindowEvent e) { 1471 } 1472 1473 public void windowLostFocus(WindowEvent e) { 1474 // Cancel a resize which may be in progress, when a 1475 // WINDOW_LOST_FOCUS event occurs, which may be 1476 // caused by an Alt-Tab or a modal dialog popup. 1477 cancelResize(); 1478 } 1479 1480 // ComponentHandler methods 1481 /** Invoked when a JInternalFrame's parent's size changes. */ 1482 public void componentResized(ComponentEvent e) { 1483 // Get the JInternalFrame's parent container size 1484 Rectangle parentNewBounds = ((Component) e.getSource()).getBounds(); 1485 JInternalFrame.JDesktopIcon icon = null; 1486 1487 if (frame != null) { 1488 icon = frame.getDesktopIcon(); 1489 // Resize the internal frame if it is maximized and relocate 1490 // the associated icon as well. 1491 if (frame.isMaximum()) { 1492 frame.setBounds(0, 0, parentNewBounds.width, 1493 parentNewBounds.height); 1494 } 1495 } 1496 1497 // Relocate the icon base on the new parent bounds. 1498 if (icon != null) { 1499 Rectangle iconBounds = icon.getBounds(); 1500 int y = iconBounds.y + 1501 (parentNewBounds.height - parentBounds.height); 1502 icon.setBounds(iconBounds.x, y, 1503 iconBounds.width, iconBounds.height); 1504 } 1505 1506 // Update the new parent bounds for next resize. 1507 if (!parentBounds.equals(parentNewBounds)) { 1508 parentBounds = parentNewBounds; 1509 } 1510 1511 // Validate the component tree for this container. 1512 if (frame != null) frame.validate(); 1513 } 1514 1515 public void componentMoved(ComponentEvent e) {} 1516 public void componentShown(ComponentEvent e) {} 1517 public void componentHidden(ComponentEvent e) {} 1518 1519 1520 // InternalFrameListener 1521 public void internalFrameClosed(InternalFrameEvent e) { 1522 frame.removeInternalFrameListener(getHandler()); 1523 } 1524 1525 public void internalFrameActivated(InternalFrameEvent e) { 1526 if (!isKeyBindingRegistered()){ 1527 setKeyBindingRegistered(true); 1528 setupMenuOpenKey(); 1529 setupMenuCloseKey(); 1530 } 1531 if (isKeyBindingRegistered()) 1532 setKeyBindingActive(true); 1533 } 1534 1535 public void internalFrameDeactivated(InternalFrameEvent e) { 1536 setKeyBindingActive(false); 1537 } 1538 1539 public void internalFrameClosing(InternalFrameEvent e) { } 1540 public void internalFrameOpened(InternalFrameEvent e) { } 1541 public void internalFrameIconified(InternalFrameEvent e) { } 1542 public void internalFrameDeiconified(InternalFrameEvent e) { } 1543 1544 1545 // LayoutManager 1546 public void addLayoutComponent(String name, Component c) {} 1547 public void removeLayoutComponent(Component c) {} 1548 public Dimension preferredLayoutSize(Container c) { 1549 Dimension result; 1550 Insets i = frame.getInsets(); 1551 1552 result = new Dimension(frame.getRootPane().getPreferredSize()); 1553 result.width += i.left + i.right; 1554 result.height += i.top + i.bottom; 1555 1556 if(getNorthPane() != null) { 1557 Dimension d = getNorthPane().getPreferredSize(); 1558 result.width = Math.max(d.width, result.width); 1559 result.height += d.height; 1560 } 1561 1562 if(getSouthPane() != null) { 1563 Dimension d = getSouthPane().getPreferredSize(); 1564 result.width = Math.max(d.width, result.width); 1565 result.height += d.height; 1566 } 1567 1568 if(getEastPane() != null) { 1569 Dimension d = getEastPane().getPreferredSize(); 1570 result.width += d.width; 1571 result.height = Math.max(d.height, result.height); 1572 } 1573 1574 if(getWestPane() != null) { 1575 Dimension d = getWestPane().getPreferredSize(); 1576 result.width += d.width; 1577 result.height = Math.max(d.height, result.height); 1578 } 1579 return result; 1580 } 1581 1582 public Dimension minimumLayoutSize(Container c) { 1583 // The minimum size of the internal frame only takes into 1584 // account the title pane since you are allowed to resize 1585 // the frames to the point where just the title pane is visible. 1586 Dimension result = new Dimension(); 1587 if (getNorthPane() != null && 1588 getNorthPane() instanceof BasicInternalFrameTitlePane) { 1589 result = new Dimension(getNorthPane().getMinimumSize()); 1590 } 1591 Insets i = frame.getInsets(); 1592 result.width += i.left + i.right; 1593 result.height += i.top + i.bottom; 1594 1595 return result; 1596 } 1597 1598 public void layoutContainer(Container c) { 1599 Insets i = frame.getInsets(); 1600 int cx, cy, cw, ch; 1601 1602 cx = i.left; 1603 cy = i.top; 1604 cw = frame.getWidth() - i.left - i.right; 1605 ch = frame.getHeight() - i.top - i.bottom; 1606 1607 if(getNorthPane() != null) { 1608 Dimension size = getNorthPane().getPreferredSize(); 1609 if (DefaultLookup.getBoolean(frame, BasicInternalFrameUI.this, 1610 "InternalFrame.layoutTitlePaneAtOrigin", false)) { 1611 cy = 0; 1612 ch += i.top; 1613 getNorthPane().setBounds(0, 0, frame.getWidth(), 1614 size.height); 1615 } 1616 else { 1617 getNorthPane().setBounds(cx, cy, cw, size.height); 1618 } 1619 cy += size.height; 1620 ch -= size.height; 1621 } 1622 1623 if(getSouthPane() != null) { 1624 Dimension size = getSouthPane().getPreferredSize(); 1625 getSouthPane().setBounds(cx, frame.getHeight() 1626 - i.bottom - size.height, 1627 cw, size.height); 1628 ch -= size.height; 1629 } 1630 1631 if(getWestPane() != null) { 1632 Dimension size = getWestPane().getPreferredSize(); 1633 getWestPane().setBounds(cx, cy, size.width, ch); 1634 cw -= size.width; 1635 cx += size.width; 1636 } 1637 1638 if(getEastPane() != null) { 1639 Dimension size = getEastPane().getPreferredSize(); 1640 getEastPane().setBounds(cw - size.width, cy, size.width, ch); 1641 cw -= size.width; 1642 } 1643 1644 if(frame.getRootPane() != null) { 1645 frame.getRootPane().setBounds(cx, cy, cw, ch); 1646 } 1647 } 1648 1649 1650 // MouseInputListener 1651 public void mousePressed(MouseEvent e) { } 1652 1653 public void mouseEntered(MouseEvent e) { } 1654 1655 public void mouseMoved(MouseEvent e) { } 1656 1657 public void mouseExited(MouseEvent e) { } 1658 1659 public void mouseClicked(MouseEvent e) { } 1660 1661 public void mouseReleased(MouseEvent e) { } 1662 1663 public void mouseDragged(MouseEvent e) { } 1664 1665 // PropertyChangeListener 1666 public void propertyChange(PropertyChangeEvent evt) { 1667 String prop = evt.getPropertyName(); 1668 JInternalFrame f = (JInternalFrame)evt.getSource(); 1669 Object newValue = evt.getNewValue(); 1670 Object oldValue = evt.getOldValue(); 1671 1672 if (JInternalFrame.IS_CLOSED_PROPERTY == prop) { 1673 if (newValue == Boolean.TRUE) { 1674 // Cancel a resize in progress if the internal frame 1675 // gets a setClosed(true) or dispose(). 1676 cancelResize(); 1677 if ((frame.getParent() != null) && componentListenerAdded) { 1678 frame.getParent().removeComponentListener(componentListener); 1679 } 1680 closeFrame(f); 1681 } 1682 } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) { 1683 if(newValue == Boolean.TRUE) { 1684 maximizeFrame(f); 1685 } else { 1686 minimizeFrame(f); 1687 } 1688 } else if(JInternalFrame.IS_ICON_PROPERTY == prop) { 1689 if (newValue == Boolean.TRUE) { 1690 iconifyFrame(f); 1691 } else { 1692 deiconifyFrame(f); 1693 } 1694 } else if (JInternalFrame.IS_SELECTED_PROPERTY == prop) { 1695 if (newValue == Boolean.TRUE && oldValue == Boolean.FALSE) { 1696 activateFrame(f); 1697 } else if (newValue == Boolean.FALSE && 1698 oldValue == Boolean.TRUE) { 1699 deactivateFrame(f); 1700 } 1701 } else if (prop == "ancestor") { 1702 if (newValue == null) { 1703 // Cancel a resize in progress, if the internal frame 1704 // gets a remove(), removeNotify() or setIcon(true). 1705 cancelResize(); 1706 } 1707 if (frame.getParent() != null) { 1708 parentBounds = f.getParent().getBounds(); 1709 } else { 1710 parentBounds = null; 1711 } 1712 if ((frame.getParent() != null) && !componentListenerAdded) { 1713 f.getParent().addComponentListener(componentListener); 1714 componentListenerAdded = true; 1715 } 1716 } else if (JInternalFrame.TITLE_PROPERTY == prop || 1717 prop == "closable" || prop == "iconable" || 1718 prop == "maximizable") { 1719 Dimension dim = frame.getMinimumSize(); 1720 Dimension frame_dim = frame.getSize(); 1721 if (dim.width > frame_dim.width) { 1722 frame.setSize(dim.width, frame_dim.height); 1723 } 1724 } 1725 } 1726 } 1727 }