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