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