001 /* BasicInternalFrameUI.java -- 002 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.swing.plaf.basic; 040 041 import java.awt.Color; 042 import java.awt.Component; 043 import java.awt.Container; 044 import java.awt.Cursor; 045 import java.awt.Dimension; 046 import java.awt.Graphics; 047 import java.awt.Insets; 048 import java.awt.LayoutManager; 049 import java.awt.LayoutManager2; 050 import java.awt.Point; 051 import java.awt.Rectangle; 052 import java.awt.event.ActionEvent; 053 import java.awt.event.ComponentEvent; 054 import java.awt.event.ComponentListener; 055 import java.awt.event.MouseEvent; 056 import java.beans.PropertyChangeEvent; 057 import java.beans.PropertyChangeListener; 058 import java.beans.PropertyVetoException; 059 060 import javax.swing.AbstractAction; 061 import javax.swing.ActionMap; 062 import javax.swing.DefaultDesktopManager; 063 import javax.swing.DesktopManager; 064 import javax.swing.JComponent; 065 import javax.swing.JDesktopPane; 066 import javax.swing.JInternalFrame; 067 import javax.swing.KeyStroke; 068 import javax.swing.LookAndFeel; 069 import javax.swing.SwingConstants; 070 import javax.swing.SwingUtilities; 071 import javax.swing.UIManager; 072 import javax.swing.border.AbstractBorder; 073 import javax.swing.event.InternalFrameEvent; 074 import javax.swing.event.InternalFrameListener; 075 import javax.swing.event.MouseInputAdapter; 076 import javax.swing.event.MouseInputListener; 077 import javax.swing.plaf.ActionMapUIResource; 078 import javax.swing.plaf.ComponentUI; 079 import javax.swing.plaf.InternalFrameUI; 080 import javax.swing.plaf.UIResource; 081 082 /** 083 * This is the UI delegate for the Basic look and feel for JInternalFrames. 084 */ 085 public class BasicInternalFrameUI extends InternalFrameUI 086 { 087 /** 088 * This is a helper class that listens to the JInternalFrame for 089 * InternalFrameEvents. 090 */ 091 protected class BasicInternalFrameListener implements InternalFrameListener 092 { 093 /** 094 * This method is called when the JInternalFrame is activated. 095 * 096 * @param e The InternalFrameEvent. 097 */ 098 public void internalFrameActivated(InternalFrameEvent e) 099 { 100 frame.getGlassPane().setVisible(false); 101 } 102 103 /** 104 * This method is called when the JInternalFrame is closed. 105 * 106 * @param e The InternalFrameEvent. 107 */ 108 public void internalFrameClosed(InternalFrameEvent e) 109 { 110 // FIXME: Implement. 111 } 112 113 /** 114 * This method is called when the JInternalFrame is closing. 115 * 116 * @param e The InternalFrameEvent. 117 */ 118 public void internalFrameClosing(InternalFrameEvent e) 119 { 120 // FIXME: Implement. 121 } 122 123 /** 124 * This method is called when the JInternalFrame is deactivated. 125 * 126 * @param e The InternalFrameEvent. 127 */ 128 public void internalFrameDeactivated(InternalFrameEvent e) 129 { 130 frame.getGlassPane().setVisible(true); 131 } 132 133 /** 134 * This method is called when the JInternalFrame is deiconified. 135 * 136 * @param e The InternalFrameEvent. 137 */ 138 public void internalFrameDeiconified(InternalFrameEvent e) 139 { 140 // FIXME: Implement. 141 } 142 143 /** 144 * This method is called when the JInternalFrame is iconified. 145 * 146 * @param e The InternalFrameEvent. 147 */ 148 public void internalFrameIconified(InternalFrameEvent e) 149 { 150 // FIXME: Implement. 151 } 152 153 /** 154 * This method is called when the JInternalFrame is opened. 155 * 156 * @param e The InternalFrameEvent. 157 */ 158 public void internalFrameOpened(InternalFrameEvent e) 159 { 160 // FIXME: Implement. 161 } 162 } 163 164 /** 165 * This helper class listens to the edges of the JInternalFrame and the 166 * TitlePane for mouse events. It is responsible for dragging and resizing 167 * the JInternalFrame in response to the MouseEvents. 168 */ 169 protected class BorderListener extends MouseInputAdapter 170 implements SwingConstants 171 { 172 /** 173 * The current shape of the cursor. 174 */ 175 transient int showingCursor; 176 177 /** FIXME: Use for something. */ 178 protected final int RESIZE_NONE = 0; 179 180 /** The x offset from the top left corner of the JInternalFrame. */ 181 private transient int xOffset; 182 183 /** The y offset from the top left corner of the JInternalFrame. */ 184 private transient int yOffset; 185 186 /** The direction that the resize is occuring in. */ 187 private transient int direction = -1; 188 189 /** Cache rectangle that can be reused. */ 190 private transient Rectangle cacheRect = new Rectangle(); 191 192 /** 193 * This method is called when the mouse is clicked. 194 * 195 * @param e The MouseEvent. 196 */ 197 public void mouseClicked(MouseEvent e) 198 { 199 // Do minimization/maximization when double-clicking in the title pane. 200 if (e.getSource() == titlePane && e.getClickCount() == 2) 201 try 202 { 203 if (frame.isMaximizable() && ! frame.isMaximum()) 204 frame.setMaximum(true); 205 else if (frame.isMaximum()) 206 frame.setMaximum(false); 207 } 208 catch (PropertyVetoException pve) 209 { 210 // We do nothing if the attempt has been vetoed. 211 } 212 213 // There is nothing to do when the mouse is clicked 214 // on the border. 215 } 216 217 /** 218 * This method is called when the mouse is dragged. This method is 219 * responsible for resizing or dragging the JInternalFrame. 220 * 221 * @param e The MouseEvent. 222 */ 223 public void mouseDragged(MouseEvent e) 224 { 225 // If the frame is maximized, there is nothing that 226 // can be dragged around. 227 if (frame.isMaximum()) 228 return; 229 DesktopManager dm = getDesktopManager(); 230 Rectangle b = frame.getBounds(); 231 Dimension min = frame.getMinimumSize(); 232 if (min == null) 233 min = new Dimension(0, 0); 234 Insets insets = frame.getInsets(); 235 int x = e.getX(); 236 int y = e.getY(); 237 if (e.getSource() == frame && frame.isResizable()) 238 { 239 switch (direction) 240 { 241 case Cursor.N_RESIZE_CURSOR: 242 cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height 243 - min.height), 244 b.width, b.height - y); 245 break; 246 case Cursor.NE_RESIZE_CURSOR: 247 cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height 248 - min.height), x + 1, 249 b.height - y); 250 break; 251 case Cursor.E_RESIZE_CURSOR: 252 cacheRect.setBounds(b.x, b.y, x + 1, b.height); 253 break; 254 case Cursor.SE_RESIZE_CURSOR: 255 cacheRect.setBounds(b.x, b.y, x + 1, y + 1); 256 break; 257 case Cursor.S_RESIZE_CURSOR: 258 cacheRect.setBounds(b.x, b.y, b.width, y + 1); 259 break; 260 case Cursor.SW_RESIZE_CURSOR: 261 cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), 262 b.y, b.width - x, y + 1); 263 break; 264 case Cursor.W_RESIZE_CURSOR: 265 cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), 266 b.y, b.width - x, b.height); 267 break; 268 case Cursor.NW_RESIZE_CURSOR: 269 cacheRect.setBounds( 270 Math.min(b.x + x, b.x + b.width - min.width), 271 Math.min(b.y + y, b.y + b.height - min.height), 272 b.width - x, b.height - y); 273 break; 274 } 275 dm.resizeFrame(frame, cacheRect.x, cacheRect.y, 276 Math.max(min.width, cacheRect.width), 277 Math.max(min.height, cacheRect.height)); 278 setCursor(e); 279 } 280 else if (e.getSource() == titlePane) 281 { 282 Rectangle fBounds = frame.getBounds(); 283 frame.putClientProperty("bufferedDragging", Boolean.TRUE); 284 dm.dragFrame(frame, e.getX() - xOffset + b.x, e.getY() - yOffset 285 + b.y); 286 } 287 } 288 289 /** 290 * This method is called when the mouse exits the JInternalFrame. 291 * 292 * @param e The MouseEvent. 293 */ 294 public void mouseExited(MouseEvent e) 295 { 296 if (showingCursor != Cursor.DEFAULT_CURSOR) 297 { 298 frame.setCursor(Cursor.getDefaultCursor()); 299 showingCursor = Cursor.DEFAULT_CURSOR; 300 } 301 } 302 303 /** 304 * This method is called when the mouse is moved inside the JInternalFrame. 305 * 306 * @param e The MouseEvent. 307 */ 308 public void mouseMoved(MouseEvent e) 309 { 310 // Turn off the resize cursor if we are in the frame header. 311 if (showingCursor != Cursor.DEFAULT_CURSOR && e.getSource() != frame) 312 { 313 frame.setCursor(Cursor.getDefaultCursor()); 314 showingCursor = Cursor.DEFAULT_CURSOR; 315 } 316 else if (e.getSource() == frame && frame.isResizable()) 317 { 318 setCursor(e); 319 } 320 } 321 322 /** 323 * Set the mouse cursor, how applicable. 324 * 325 * @param e the current mouse event. 326 */ 327 void setCursor(MouseEvent e) 328 { 329 int cursor = sectionOfClick(e.getX(), e.getY()); 330 if (cursor != showingCursor) 331 { 332 Cursor resize = Cursor.getPredefinedCursor(cursor); 333 frame.setCursor(resize); 334 showingCursor = cursor; 335 } 336 } 337 338 /** 339 * This method is called when the mouse is pressed. 340 * 341 * @param e The MouseEvent. 342 */ 343 public void mousePressed(MouseEvent e) 344 { 345 activateFrame(frame); 346 DesktopManager dm = getDesktopManager(); 347 int x = e.getX(); 348 int y = e.getY(); 349 Insets insets = frame.getInsets(); 350 351 if (e.getSource() == frame && frame.isResizable()) 352 { 353 direction = sectionOfClick(x, y); 354 dm.beginResizingFrame(frame, direction); 355 } 356 else if (e.getSource() == titlePane) 357 { 358 Rectangle tBounds = titlePane.getBounds(); 359 360 xOffset = e.getX() - tBounds.x + insets.left; 361 yOffset = e.getY() - tBounds.y + insets.top; 362 363 dm.beginDraggingFrame(frame); 364 } 365 } 366 367 /** 368 * This method is called when the mouse is released. 369 * 370 * @param e The MouseEvent. 371 */ 372 public void mouseReleased(MouseEvent e) 373 { 374 DesktopManager dm = getDesktopManager(); 375 xOffset = 0; 376 yOffset = 0; 377 if (e.getSource() == frame && frame.isResizable()) 378 dm.endResizingFrame(frame); 379 else if (e.getSource() == titlePane) 380 { 381 dm.endDraggingFrame(frame); 382 frame.putClientProperty("bufferedDragging", null); 383 } 384 385 setCursor(e); 386 } 387 388 /** 389 * This method determines the direction of the resize based on the 390 * coordinates and the size of the JInternalFrame. 391 * 392 * @param x The x coordinate of the MouseEvent. 393 * @param y The y coordinate of the MouseEvent. 394 * 395 * @return The cursor constant, determining the resizing direction. 396 */ 397 private int sectionOfClick(int x, int y) 398 { 399 Rectangle b = frame.getBounds(); 400 int corner = InternalFrameBorder.cornerSize; 401 402 if (x < corner && y < corner) 403 return Cursor.NW_RESIZE_CURSOR; 404 else if (x > b.width - corner && y < corner) 405 return Cursor.NE_RESIZE_CURSOR; 406 else if (x > b.width - corner && y > b.height - corner) 407 return Cursor.SE_RESIZE_CURSOR; 408 else if (x < corner && y > b.height - corner) 409 return Cursor.SW_RESIZE_CURSOR; 410 else if (y < corner) 411 return Cursor.N_RESIZE_CURSOR; 412 else if (x < corner) 413 return Cursor.W_RESIZE_CURSOR; 414 else if (y > b.height - corner) 415 return Cursor.S_RESIZE_CURSOR; 416 else if (x > b.width - corner) 417 return Cursor.E_RESIZE_CURSOR; 418 419 return Cursor.DEFAULT_CURSOR; 420 } 421 } 422 423 /** 424 * This helper class listens to the JDesktopPane that parents this 425 * JInternalFrame and listens for resize events and resizes the 426 * JInternalFrame appropriately. 427 */ 428 protected class ComponentHandler implements ComponentListener 429 { 430 /** 431 * This method is called when the JDesktopPane is hidden. 432 * 433 * @param e 434 * The ComponentEvent fired. 435 */ 436 public void componentHidden(ComponentEvent e) 437 { 438 // Do nothing. 439 } 440 441 /** 442 * This method is called when the JDesktopPane is moved. 443 * 444 * @param e 445 * The ComponentEvent fired. 446 */ 447 public void componentMoved(ComponentEvent e) 448 { 449 // Do nothing. 450 } 451 452 /** 453 * This method is called when the JDesktopPane is resized. 454 * 455 * @param e 456 * The ComponentEvent fired. 457 */ 458 public void componentResized(ComponentEvent e) 459 { 460 if (frame.isMaximum()) 461 { 462 Container parent = frame.getParent(); 463 Insets i = parent.getInsets(); 464 int width = parent.getWidth() - i.left - i.right; 465 int height = parent.getHeight() - i.top - i.bottom; 466 frame.setBounds(0, 0, width, height); 467 } 468 } 469 470 /** 471 * This method is called when the JDesktopPane is shown. 472 * 473 * @param e 474 * The ComponentEvent fired. 475 */ 476 public void componentShown(ComponentEvent e) 477 { 478 // Do nothing. 479 } 480 } 481 482 /** 483 * This helper class acts as the LayoutManager for JInternalFrames. 484 */ 485 public class InternalFrameLayout implements LayoutManager 486 { 487 /** 488 * This method is called when the given Component is added to the 489 * JInternalFrame. 490 * 491 * @param name 492 * The name of the Component. 493 * @param c 494 * The Component added. 495 */ 496 public void addLayoutComponent(String name, Component c) 497 { 498 // Nothing to do here. 499 } 500 501 /** 502 * This method is used to set the bounds of the children of the 503 * JInternalFrame. 504 * 505 * @param c 506 * The Container to lay out. 507 */ 508 public void layoutContainer(Container c) 509 { 510 Dimension dims = frame.getSize(); 511 Insets insets = frame.getInsets(); 512 513 dims.width -= insets.left + insets.right; 514 dims.height -= insets.top + insets.bottom; 515 516 int nh = 0; 517 int sh = 0; 518 int ew = 0; 519 int ww = 0; 520 521 if (northPane != null) 522 { 523 Dimension nDims = northPane.getPreferredSize(); 524 nh = Math.min(nDims.height, dims.height); 525 526 northPane.setBounds(insets.left, insets.top, dims.width, nh); 527 } 528 529 if (southPane != null) 530 { 531 Dimension sDims = southPane.getPreferredSize(); 532 sh = Math.min(sDims.height, dims.height - nh); 533 534 southPane.setBounds(insets.left, insets.top + dims.height - sh, 535 dims.width, sh); 536 } 537 538 int remHeight = dims.height - sh - nh; 539 540 if (westPane != null) 541 { 542 Dimension wDims = westPane.getPreferredSize(); 543 ww = Math.min(dims.width, wDims.width); 544 545 westPane.setBounds(insets.left, insets.top + nh, ww, remHeight); 546 } 547 548 if (eastPane != null) 549 { 550 Dimension eDims = eastPane.getPreferredSize(); 551 ew = Math.min(eDims.width, dims.width - ww); 552 553 eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh, 554 ew, remHeight); 555 } 556 557 int remWidth = dims.width - ww - ew; 558 559 frame.getRootPane().setBounds(insets.left + ww, insets.top + nh, 560 remWidth, remHeight); 561 } 562 563 /** 564 * This method returns the minimum layout size. 565 * 566 * @param c 567 * The Container to find a minimum layout size for. 568 * @return The minimum dimensions for the JInternalFrame. 569 */ 570 public Dimension minimumLayoutSize(Container c) 571 { 572 return getSize(c, true); 573 } 574 575 /** 576 * Th8is method returns the preferred layout size. 577 * 578 * @param c 579 * The Container to find a preferred layout size for. 580 * @return The preferred dimensions for the JInternalFrame. 581 */ 582 public Dimension preferredLayoutSize(Container c) 583 { 584 return getSize(c, false); 585 } 586 587 /** 588 * DOCUMENT ME! 589 * 590 * @param c 591 * DOCUMENT ME! 592 * @param min 593 * DOCUMENT ME! 594 * @return DOCUMENT ME! 595 */ 596 private Dimension getSize(Container c, boolean min) 597 { 598 Insets insets = frame.getInsets(); 599 600 Dimension contentDims = frame.getContentPane().getPreferredSize(); 601 if (min) 602 contentDims.width = contentDims.height = 0; 603 int nWidth = 0; 604 int nHeight = 0; 605 int sWidth = 0; 606 int sHeight = 0; 607 int eWidth = 0; 608 int eHeight = 0; 609 int wWidth = 0; 610 int wHeight = 0; 611 Dimension dims; 612 613 if (northPane != null) 614 { 615 dims = northPane.getPreferredSize(); 616 if (dims != null) 617 { 618 nWidth = dims.width; 619 nHeight = dims.height; 620 } 621 } 622 623 if (southPane != null) 624 { 625 dims = southPane.getPreferredSize(); 626 if (dims != null) 627 { 628 sWidth = dims.width; 629 sHeight = dims.height; 630 } 631 } 632 633 if (eastPane != null) 634 { 635 dims = eastPane.getPreferredSize(); 636 if (dims != null) 637 { 638 sWidth = dims.width; 639 sHeight = dims.height; 640 } 641 } 642 643 if (westPane != null) 644 { 645 dims = westPane.getPreferredSize(); 646 if (dims != null) 647 { 648 wWidth = dims.width; 649 wHeight = dims.height; 650 } 651 } 652 653 int width = Math.max(sWidth, nWidth); 654 width = Math.max(width, contentDims.width + eWidth + wWidth); 655 656 int height = Math.max(eHeight, wHeight); 657 height = Math.max(height, contentDims.height); 658 height += nHeight + sHeight; 659 660 width += insets.left + insets.right; 661 height += insets.top + insets.bottom; 662 663 return new Dimension(width, height); 664 } 665 666 /** 667 * This method is called when a Component is removed from the 668 * JInternalFrame. 669 * 670 * @param c The Component that was removed. 671 */ 672 public void removeLayoutComponent(Component c) 673 { 674 // Nothing to do here. 675 } 676 } 677 678 /** 679 * This helper class is used to listen to the JDesktopPane's glassPane for 680 * MouseEvents. The JInternalFrame can then be selected if a click is 681 * detected on its children. 682 */ 683 protected class GlassPaneDispatcher implements MouseInputListener 684 { 685 /** The MouseEvent target. */ 686 private transient Component mouseEventTarget; 687 688 private Component dragTarget; 689 690 /** 691 * Indicates if we are currently in a dragging operation or not. 692 */ 693 private boolean isDragging; 694 695 /** 696 * This method is called when the mouse enters the glass pane. 697 * 698 * @param e 699 * The MouseEvent. 700 */ 701 public void mouseEntered(MouseEvent e) 702 { 703 handleEvent(e); 704 } 705 706 /** 707 * This method is called when the mouse is clicked on the glass pane. 708 * 709 * @param e 710 * The MouseEvent. 711 */ 712 public void mouseClicked(MouseEvent e) 713 { 714 handleEvent(e); 715 } 716 717 /** 718 * This method is called when the mouse is dragged in the glass pane. 719 * 720 * @param e 721 * The MouseEvent. 722 */ 723 public void mouseDragged(MouseEvent e) 724 { 725 handleEvent(e); 726 } 727 728 /** 729 * This method is called when the mouse exits the glass pane. 730 * 731 * @param e 732 * The MouseEvent. 733 */ 734 public void mouseExited(MouseEvent e) 735 { 736 handleEvent(e); 737 } 738 739 /** 740 * This method is called when the mouse is moved in the glass pane. 741 * 742 * @param e 743 * The MouseEvent. 744 */ 745 public void mouseMoved(MouseEvent e) 746 { 747 handleEvent(e); 748 } 749 750 /** 751 * This method is called when the mouse is pressed in the glass pane. 752 * 753 * @param e 754 * The MouseEvent. 755 */ 756 public void mousePressed(MouseEvent e) 757 { 758 // Experiments show that this seems to call the 759 // borderListener.mousePressed() method to activate the frame. 760 if (borderListener != null) 761 borderListener.mousePressed(e); 762 handleEvent(e); 763 } 764 765 /** 766 * This method is called when the mouse is released in the glass pane. 767 * 768 * @param e 769 * The MouseEvent. 770 */ 771 public void mouseReleased(MouseEvent e) 772 { 773 handleEvent(e); 774 } 775 776 /** 777 * This is a helper method that dispatches the GlassPane MouseEvents to the 778 * proper component. 779 * 780 * @param e the mouse event to be dispatched 781 */ 782 private void handleEvent(MouseEvent e) 783 { 784 // Find candidate component inside the JInternalFrame. 785 Component target = frame.getLayeredPane().findComponentAt(e.getX(), 786 e.getY()); 787 788 // Now search upwards to find a component that actually has 789 // a MouseListener attached. 790 while (target != null 791 && target.getMouseListeners().length == 0 792 && target.getMouseMotionListeners().length == 0 793 && target.getMouseWheelListeners().length == 0) 794 { 795 target = target.getParent(); 796 } 797 798 if (target != null) 799 { 800 int id = e.getID(); 801 switch (id) 802 { 803 case MouseEvent.MOUSE_ENTERED: 804 // Now redispatch the thing. 805 if (! isDragging || frame.isSelected()) 806 { 807 mouseEventTarget = target; 808 redispatch(id, e, mouseEventTarget); 809 } 810 break; 811 case MouseEvent.MOUSE_EXITED: 812 if (! isDragging || frame.isSelected()) 813 { 814 redispatch(id, e, mouseEventTarget); 815 } 816 break; 817 case MouseEvent.MOUSE_PRESSED: 818 mouseEventTarget = target; 819 redispatch(id, e, mouseEventTarget); 820 // Start dragging. 821 dragTarget = target; 822 break; 823 case MouseEvent.MOUSE_RELEASED: 824 if (isDragging) 825 { 826 redispatch(id, e, dragTarget); 827 isDragging = false; 828 } 829 else 830 redispatch(id, e, mouseEventTarget); 831 break; 832 case MouseEvent.MOUSE_CLICKED: 833 redispatch(id, e, mouseEventTarget); 834 break; 835 case MouseEvent.MOUSE_MOVED: 836 if (target != mouseEventTarget) 837 { 838 // Create additional MOUSE_EXITED/MOUSE_ENTERED pairs. 839 redispatch(MouseEvent.MOUSE_EXITED, e, mouseEventTarget); 840 mouseEventTarget = target; 841 redispatch(MouseEvent.MOUSE_ENTERED, e, mouseEventTarget); 842 } 843 redispatch(id, e, mouseEventTarget); 844 break; 845 case MouseEvent.MOUSE_DRAGGED: 846 if (! isDragging) 847 isDragging = true; 848 redispatch(id, e, mouseEventTarget); 849 break; 850 case MouseEvent.MOUSE_WHEEL: 851 redispatch(id, e, mouseEventTarget); 852 break; 853 default: 854 assert false : "Must not reach here"; 855 } 856 } 857 } 858 859 /** 860 * Redispatches the event to the real target with the specified id. 861 * 862 * @param id the new event ID 863 * @param e the original event 864 * @param target the real event target 865 */ 866 private void redispatch(int id, MouseEvent e, Component target) 867 { 868 Point p = SwingUtilities.convertPoint(frame.getLayeredPane(), e.getX(), 869 e.getY(), target); 870 MouseEvent ev = new MouseEvent(target, id, e.getWhen(), 871 e.getModifiers() | e.getModifiersEx(), 872 p.x, p.y, e.getClickCount(), 873 e.isPopupTrigger()); 874 target.dispatchEvent(ev); 875 } 876 } 877 878 /** 879 * This helper class listens for PropertyChangeEvents from the 880 * JInternalFrame. 881 */ 882 public class InternalFramePropertyChangeListener 883 implements PropertyChangeListener 884 { 885 886 /** 887 * This method is called when one of the JInternalFrame's properties change. 888 * 889 * @param evt 890 * The PropertyChangeEvent. 891 */ 892 public void propertyChange(PropertyChangeEvent evt) 893 { 894 String property = evt.getPropertyName(); 895 if (property.equals(JInternalFrame.IS_MAXIMUM_PROPERTY)) 896 { 897 if (frame.isMaximum()) 898 maximizeFrame(frame); 899 else 900 minimizeFrame(frame); 901 } 902 else if (property.equals(JInternalFrame.IS_ICON_PROPERTY)) 903 { 904 if (frame.isIcon()) 905 iconifyFrame(frame); 906 else 907 deiconifyFrame(frame); 908 } 909 else if (property.equals(JInternalFrame.IS_SELECTED_PROPERTY)) 910 { 911 Component glassPane = frame.getGlassPane(); 912 if (frame.isSelected()) 913 { 914 activateFrame(frame); 915 glassPane.setVisible(false); 916 } 917 else 918 { 919 deactivateFrame(frame); 920 glassPane.setVisible(true); 921 } 922 } 923 else if (property.equals(JInternalFrame.ROOT_PANE_PROPERTY) 924 || property.equals(JInternalFrame.GLASS_PANE_PROPERTY)) 925 { 926 Component old = (Component) evt.getOldValue(); 927 if (old != null) 928 { 929 old.removeMouseListener(glassPaneDispatcher); 930 old.removeMouseMotionListener(glassPaneDispatcher); 931 } 932 933 Component newPane = (Component) evt.getNewValue(); 934 if (newPane != null) 935 { 936 newPane.addMouseListener(glassPaneDispatcher); 937 newPane.addMouseMotionListener(glassPaneDispatcher); 938 } 939 940 frame.revalidate(); 941 } 942 else if (property.equals(JInternalFrame.IS_CLOSED_PROPERTY)) 943 { 944 if (evt.getNewValue() == Boolean.TRUE) 945 { 946 Container parent = frame.getParent(); 947 if (parent != null) 948 parent.removeComponentListener(componentListener); 949 closeFrame(frame); 950 } 951 } 952 else if (property.equals("ancestor")) 953 { 954 Container newParent = (Container) evt.getNewValue(); 955 Container oldParent = (Container) evt.getOldValue(); 956 if (newParent != null) 957 { 958 newParent.addComponentListener(componentListener); 959 } 960 else if (oldParent != null) 961 { 962 oldParent.removeComponentListener(componentListener); 963 } 964 } 965 } 966 } 967 968 /** 969 * This helper class is the border for the JInternalFrame. 970 */ 971 class InternalFrameBorder extends AbstractBorder implements 972 UIResource 973 { 974 /** 975 * The width of the border. 976 */ 977 static final int bSize = 5; 978 979 /** 980 * The size of the corners (also used by the mouse listener). 981 */ 982 static final int cornerSize = 10; 983 984 /** 985 * This method returns whether the border is opaque. 986 * 987 * @return Whether the border is opaque. 988 */ 989 public boolean isBorderOpaque() 990 { 991 return true; 992 } 993 994 /** 995 * This method returns the insets of the border. 996 * 997 * @param c 998 * The Component to find border insets for. 999 * @return The border insets. 1000 */ 1001 public Insets getBorderInsets(Component c) 1002 { 1003 return new Insets(bSize, bSize, bSize, bSize); 1004 } 1005 1006 /** 1007 * This method paints the border. 1008 * 1009 * @param c 1010 * The Component that owns the border. 1011 * @param g 1012 * The Graphics object to paint with. 1013 * @param x 1014 * The x coordinate to paint at. 1015 * @param y 1016 * The y coordinate to paint at. 1017 * @param width 1018 * The width of the Component. 1019 * @param height 1020 * The height of the Component. 1021 */ 1022 public void paintBorder(Component c, Graphics g, int x, int y, int width, 1023 int height) 1024 { 1025 g.translate(x, y); 1026 Color saved = g.getColor(); 1027 Rectangle b = frame.getBounds(); 1028 1029 Color d = c.getBackground(); 1030 g.setColor(d); 1031 g.fillRect(0, 0, bSize, b.height); 1032 g.fillRect(0, 0, b.width, bSize); 1033 g.fillRect(0, b.height - bSize, b.width, bSize); 1034 g.fillRect(b.width - bSize, 0, bSize, b.height); 1035 1036 int x1 = 0; 1037 int x2 = bSize; 1038 int x3 = b.width - bSize; 1039 int x4 = b.width; 1040 1041 int y1 = 0; 1042 int y2 = bSize; 1043 int y3 = b.height - bSize; 1044 int y4 = b.height; 1045 1046 g.setColor(Color.GRAY); 1047 g.fillRect(0, 0, bSize, y4); 1048 g.fillRect(0, 0, x4, bSize); 1049 g.fillRect(0, y3, b.width, bSize); 1050 g.fillRect(x3, 0, bSize, b.height); 1051 1052 g.fill3DRect(0, cornerSize, bSize, b.height - 2 * cornerSize, false); 1053 g.fill3DRect(cornerSize, 0, b.width - 2 * cornerSize, bSize, false); 1054 g.fill3DRect(cornerSize, b.height - bSize, b.width - 2 * cornerSize, 1055 bSize, false); 1056 g.fill3DRect(b.width - bSize, cornerSize, bSize, 1057 b.height - 2 * cornerSize, false); 1058 1059 g.translate(-x, -y); 1060 g.setColor(saved); 1061 } 1062 } 1063 1064 /** 1065 * This action triggers the system menu. 1066 * 1067 * @author Roman Kennke (kennke@aicas.com) 1068 */ 1069 private class ShowSystemMenuAction 1070 extends AbstractAction 1071 { 1072 public void actionPerformed(ActionEvent e) 1073 { 1074 if (titlePane != null) 1075 { 1076 titlePane.showSystemMenu(); 1077 } 1078 } 1079 } 1080 1081 /** 1082 * The MouseListener that is responsible for dragging and resizing the 1083 * JInternalFrame in response to MouseEvents. 1084 */ 1085 protected MouseInputAdapter borderListener; 1086 1087 /** 1088 * The ComponentListener that is responsible for resizing the JInternalFrame 1089 * in response to ComponentEvents from the JDesktopPane. 1090 */ 1091 protected ComponentListener componentListener; 1092 1093 /** 1094 * The MouseListener that is responsible for activating the JInternalFrame 1095 * when the mouse press activates one of its descendents. 1096 */ 1097 protected MouseInputListener glassPaneDispatcher; 1098 1099 /** 1100 * The PropertyChangeListener that is responsible for listening to 1101 * PropertyChangeEvents from the JInternalFrame. 1102 */ 1103 protected PropertyChangeListener propertyChangeListener; 1104 1105 /** The InternalFrameListener that listens to the JInternalFrame. */ 1106 private transient BasicInternalFrameListener internalFrameListener; 1107 1108 /** The JComponent placed at the east region of the JInternalFrame. */ 1109 protected JComponent eastPane; 1110 1111 /** The JComponent placed at the north region of the JInternalFrame. */ 1112 protected JComponent northPane; 1113 1114 /** The JComponent placed at the south region of the JInternalFrame. */ 1115 protected JComponent southPane; 1116 1117 /** The JComponent placed at the west region of the JInternalFrame. */ 1118 protected JComponent westPane; 1119 1120 /** 1121 * The Keystroke bound to open the menu. 1122 * @deprecated 1123 */ 1124 protected KeyStroke openMenuKey; 1125 1126 /** The TitlePane displayed at the top of the JInternalFrame. */ 1127 protected BasicInternalFrameTitlePane titlePane; 1128 1129 /** The JInternalFrame this UI is responsible for. */ 1130 protected JInternalFrame frame; 1131 1132 /** The LayoutManager used in the JInternalFrame. */ 1133 protected LayoutManager internalFrameLayout; 1134 1135 /** The JDesktopPane that is the parent of the JInternalFrame. */ 1136 private transient JDesktopPane desktopPane; 1137 1138 /** 1139 * Creates a new BasicInternalFrameUI object. 1140 * 1141 * @param b The JInternalFrame this UI will represent. 1142 */ 1143 public BasicInternalFrameUI(JInternalFrame b) 1144 { 1145 // Nothing to do here. 1146 } 1147 1148 /** 1149 * This method will create a new BasicInternalFrameUI for the given 1150 * JComponent. 1151 * 1152 * @param b The JComponent to create a BasicInternalFrameUI for. 1153 * 1154 * @return A new BasicInternalFrameUI. 1155 */ 1156 public static ComponentUI createUI(JComponent b) 1157 { 1158 return new BasicInternalFrameUI((JInternalFrame) b); 1159 } 1160 1161 /** 1162 * This method installs a UI for the JInternalFrame. 1163 * 1164 * @param c The JComponent to install this UI on. 1165 */ 1166 public void installUI(JComponent c) 1167 { 1168 if (c instanceof JInternalFrame) 1169 { 1170 frame = (JInternalFrame) c; 1171 1172 installDefaults(); 1173 installListeners(); 1174 installComponents(); 1175 installKeyboardActions(); 1176 1177 if (! frame.isSelected()) 1178 frame.getGlassPane().setVisible(true); 1179 } 1180 } 1181 1182 /** 1183 * This method reverses the work done by installUI. 1184 * 1185 * @param c The JComponent to uninstall this UI for. 1186 */ 1187 public void uninstallUI(JComponent c) 1188 { 1189 uninstallKeyboardActions(); 1190 uninstallComponents(); 1191 uninstallListeners(); 1192 uninstallDefaults(); 1193 1194 frame.getRootPane().getGlassPane().setVisible(false); 1195 frame = null; 1196 } 1197 1198 /** 1199 * This method installs the defaults specified by the look and feel. 1200 */ 1201 protected void installDefaults() 1202 { 1203 internalFrameLayout = createLayoutManager(); 1204 frame.setLayout(internalFrameLayout); 1205 LookAndFeel.installBorder(frame, "InternalFrame.border"); 1206 frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon")); 1207 1208 // Let the content pane inherit the background color from its 1209 // frame by setting the background to null. 1210 Component contentPane = frame.getContentPane(); 1211 if (contentPane != null 1212 && contentPane.getBackground() instanceof UIResource) 1213 { 1214 contentPane.setBackground(null); 1215 } 1216 } 1217 1218 /** 1219 * This method installs the keyboard actions for the JInternalFrame. 1220 */ 1221 protected void installKeyboardActions() 1222 { 1223 ActionMapUIResource am = new ActionMapUIResource(); 1224 am.put("showSystemMenu", new ShowSystemMenuAction()); 1225 1226 // The RI impl installs the audio actions as parent of the UI action map, 1227 // so do we. 1228 BasicLookAndFeel blaf = (BasicLookAndFeel) UIManager.getLookAndFeel(); 1229 ActionMap audioActionMap = blaf.getAudioActionMap(); 1230 am.setParent(audioActionMap); 1231 1232 SwingUtilities.replaceUIActionMap(frame, am); 1233 } 1234 1235 /** 1236 * This method installs the Components for the JInternalFrame. 1237 */ 1238 protected void installComponents() 1239 { 1240 setNorthPane(createNorthPane(frame)); 1241 setSouthPane(createSouthPane(frame)); 1242 setEastPane(createEastPane(frame)); 1243 setWestPane(createWestPane(frame)); 1244 } 1245 1246 /** 1247 * This method installs the listeners for the JInternalFrame. 1248 */ 1249 protected void installListeners() 1250 { 1251 glassPaneDispatcher = createGlassPaneDispatcher(); 1252 createInternalFrameListener(); 1253 borderListener = createBorderListener(frame); 1254 componentListener = createComponentListener(); 1255 propertyChangeListener = createPropertyChangeListener(); 1256 1257 frame.addMouseListener(borderListener); 1258 frame.addMouseMotionListener(borderListener); 1259 frame.addInternalFrameListener(internalFrameListener); 1260 frame.addPropertyChangeListener(propertyChangeListener); 1261 frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher); 1262 frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher); 1263 1264 Container parent = frame.getParent(); 1265 if (parent != null) 1266 { 1267 parent.addComponentListener(componentListener); 1268 } 1269 } 1270 1271 /** 1272 * This method uninstalls the defaults for the JInternalFrame. 1273 */ 1274 protected void uninstallDefaults() 1275 { 1276 frame.setBorder(null); 1277 frame.setLayout(null); 1278 internalFrameLayout = null; 1279 } 1280 1281 /** 1282 * This method uninstalls the Components for the JInternalFrame. 1283 */ 1284 protected void uninstallComponents() 1285 { 1286 setNorthPane(null); 1287 setSouthPane(null); 1288 setEastPane(null); 1289 setWestPane(null); 1290 } 1291 1292 /** 1293 * This method uninstalls the listeners for the JInternalFrame. 1294 */ 1295 protected void uninstallListeners() 1296 { 1297 1298 Container parent = frame.getParent(); 1299 if (parent != null) 1300 { 1301 parent.removeComponentListener(componentListener); 1302 } 1303 componentListener = null; 1304 1305 frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher); 1306 frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher); 1307 1308 frame.removePropertyChangeListener(propertyChangeListener); 1309 frame.removeInternalFrameListener(internalFrameListener); 1310 frame.removeMouseMotionListener(borderListener); 1311 frame.removeMouseListener(borderListener); 1312 1313 propertyChangeListener = null; 1314 1315 borderListener = null; 1316 internalFrameListener = null; 1317 glassPaneDispatcher = null; 1318 } 1319 1320 /** 1321 * This method uninstalls the keyboard actions for the JInternalFrame. 1322 */ 1323 protected void uninstallKeyboardActions() 1324 { 1325 SwingUtilities.replaceUIActionMap(frame, null); 1326 SwingUtilities.replaceUIInputMap(frame, JComponent.WHEN_IN_FOCUSED_WINDOW, 1327 null); 1328 } 1329 1330 /** 1331 * This method creates a new LayoutManager for the JInternalFrame. 1332 * 1333 * @return A new LayoutManager for the JInternalFrame. 1334 */ 1335 protected LayoutManager createLayoutManager() 1336 { 1337 return new InternalFrameLayout(); 1338 } 1339 1340 /** 1341 * This method creates a new PropertyChangeListener for the JInternalFrame. 1342 * 1343 * @return A new PropertyChangeListener for the JInternalFrame. 1344 */ 1345 protected PropertyChangeListener createPropertyChangeListener() 1346 { 1347 return new InternalFramePropertyChangeListener(); 1348 } 1349 1350 /** 1351 * This method returns the preferred size of the given JComponent. 1352 * 1353 * @param x The JComponent to find a preferred size for. 1354 * 1355 * @return The preferred size. 1356 */ 1357 public Dimension getPreferredSize(JComponent x) 1358 { 1359 Dimension pref = null; 1360 LayoutManager layout = frame.getLayout(); 1361 if (frame == x && layout != null) 1362 pref = layout.preferredLayoutSize(frame); 1363 else 1364 pref = new Dimension(100, 100); 1365 return pref; 1366 } 1367 1368 /** 1369 * This method returns the minimum size of the given JComponent. 1370 * 1371 * @param x The JComponent to find a minimum size for. 1372 * 1373 * @return The minimum size. 1374 */ 1375 public Dimension getMinimumSize(JComponent x) 1376 { 1377 Dimension min = null; 1378 LayoutManager layout = frame.getLayout(); 1379 if (frame == x && layout != null) 1380 min = layout.minimumLayoutSize(frame); 1381 else 1382 min = new Dimension(0, 0); 1383 return min; 1384 } 1385 1386 /** 1387 * This method returns the maximum size of the given JComponent. 1388 * 1389 * @param x The JComponent to find a maximum size for. 1390 * 1391 * @return The maximum size. 1392 */ 1393 public Dimension getMaximumSize(JComponent x) 1394 { 1395 Dimension max = null; 1396 LayoutManager layout = frame.getLayout(); 1397 if (frame == x && layout != null && layout instanceof LayoutManager2) 1398 max = ((LayoutManager2) layout).maximumLayoutSize(frame); 1399 else 1400 max = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 1401 return max; 1402 } 1403 1404 /** 1405 * This method replaces the currentPane with the newPane. When replacing it 1406 * also removes the MouseHandlers for the old pane and installs them on 1407 * the new pane. 1408 * 1409 * @param currentPane The old pane to remove. 1410 * @param newPane The new pane to install. 1411 */ 1412 protected void replacePane(JComponent currentPane, JComponent newPane) 1413 { 1414 if (currentPane != null) 1415 { 1416 deinstallMouseHandlers(currentPane); 1417 frame.remove(currentPane); 1418 } 1419 1420 if (newPane != null) 1421 { 1422 installMouseHandlers(newPane); 1423 frame.add(newPane); 1424 } 1425 } 1426 1427 /** 1428 * This method removes the necessary MouseListeners from the given 1429 * JComponent. 1430 * 1431 * @param c The JComponent to remove MouseListeners from. 1432 */ 1433 protected void deinstallMouseHandlers(JComponent c) 1434 { 1435 c.removeMouseListener(borderListener); 1436 c.removeMouseMotionListener(borderListener); 1437 } 1438 1439 /** 1440 * This method installs the necessary MouseListeners from the given 1441 * JComponent. 1442 * 1443 * @param c The JComponent to install MouseListeners on. 1444 */ 1445 protected void installMouseHandlers(JComponent c) 1446 { 1447 c.addMouseListener(borderListener); 1448 c.addMouseMotionListener(borderListener); 1449 } 1450 1451 /** 1452 * This method creates the north pane used in the JInternalFrame. 1453 * 1454 * @param w The JInternalFrame to create a north pane for. 1455 * 1456 * @return The north pane. 1457 */ 1458 protected JComponent createNorthPane(JInternalFrame w) 1459 { 1460 titlePane = new BasicInternalFrameTitlePane(w); 1461 return titlePane; 1462 } 1463 1464 /** 1465 * This method creates the west pane used in the JInternalFrame. 1466 * 1467 * @param w The JInternalFrame to create a west pane for. 1468 * 1469 * @return The west pane. 1470 */ 1471 protected JComponent createWestPane(JInternalFrame w) 1472 { 1473 return null; 1474 } 1475 1476 /** 1477 * This method creates the south pane used in the JInternalFrame. 1478 * 1479 * @param w The JInternalFrame to create a south pane for. 1480 * 1481 * @return The south pane. 1482 */ 1483 protected JComponent createSouthPane(JInternalFrame w) 1484 { 1485 return null; 1486 } 1487 1488 /** 1489 * This method creates the east pane used in the JInternalFrame. 1490 * 1491 * @param w The JInternalFrame to create an east pane for. 1492 * 1493 * @return The east pane. 1494 */ 1495 protected JComponent createEastPane(JInternalFrame w) 1496 { 1497 return null; 1498 } 1499 1500 /** 1501 * This method returns a new BorderListener for the given JInternalFrame. 1502 * 1503 * @param w The JIntenalFrame to create a BorderListener for. 1504 * 1505 * @return A new BorderListener. 1506 */ 1507 protected MouseInputAdapter createBorderListener(JInternalFrame w) 1508 { 1509 return new BorderListener(); 1510 } 1511 1512 /** 1513 * This method creates a new InternalFrameListener for the JInternalFrame. 1514 */ 1515 protected void createInternalFrameListener() 1516 { 1517 internalFrameListener = new BasicInternalFrameListener(); 1518 } 1519 1520 /** 1521 * DOCUMENT ME! 1522 * 1523 * @return DOCUMENT ME! 1524 */ 1525 protected final boolean isKeyBindingRegistered() 1526 { 1527 // FIXME: Implement. 1528 return false; 1529 } 1530 1531 /** 1532 * DOCUMENT ME! 1533 * 1534 * @param b DOCUMENT ME! 1535 */ 1536 protected final void setKeyBindingRegistered(boolean b) 1537 { 1538 // FIXME: Implement. 1539 } 1540 1541 /** 1542 * DOCUMENT ME! 1543 * 1544 * @return DOCUMENT ME! 1545 */ 1546 public final boolean isKeyBindingActive() 1547 { 1548 // FIXME: Implement. 1549 return false; 1550 } 1551 1552 /** 1553 * DOCUMENT ME! 1554 * 1555 * @param b DOCUMENT ME! 1556 */ 1557 protected final void setKeyBindingActive(boolean b) 1558 { 1559 // FIXME: Implement. 1560 } 1561 1562 /** 1563 * DOCUMENT ME! 1564 */ 1565 protected void setupMenuOpenKey() 1566 { 1567 // FIXME: Implement. 1568 } 1569 1570 /** 1571 * DOCUMENT ME! 1572 */ 1573 protected void setupMenuCloseKey() 1574 { 1575 // FIXME: Implement. 1576 } 1577 1578 /** 1579 * This method returns the north pane. 1580 * 1581 * @return The north pane. 1582 */ 1583 public JComponent getNorthPane() 1584 { 1585 return northPane; 1586 } 1587 1588 /** 1589 * This method sets the north pane to be the given JComponent. 1590 * 1591 * @param c The new north pane. 1592 */ 1593 public void setNorthPane(JComponent c) 1594 { 1595 replacePane(northPane, c); 1596 northPane = c; 1597 // the following is needed to make internal frames draggable when using 1598 // the JGoodies PlasticLookAndFeel, because it overrides the 1599 // createNorthPane() method and doesn't assign anything to the titlePane 1600 // field. It is possible there is another way to make this work, but 1601 // I didn't find it... 1602 if (c instanceof BasicInternalFrameTitlePane) 1603 titlePane = (BasicInternalFrameTitlePane) c; 1604 } 1605 1606 /** 1607 * This method returns the south pane. 1608 * 1609 * @return The south pane. 1610 */ 1611 public JComponent getSouthPane() 1612 { 1613 return southPane; 1614 } 1615 1616 /** 1617 * This method sets the south pane to be the given JComponent. 1618 * 1619 * @param c The new south pane. 1620 */ 1621 public void setSouthPane(JComponent c) 1622 { 1623 replacePane(southPane, c); 1624 southPane = c; 1625 } 1626 1627 /** 1628 * This method sets the east pane to be the given JComponent. 1629 * 1630 * @param c The new east pane. 1631 */ 1632 public void setEastPane(JComponent c) 1633 { 1634 replacePane(eastPane, c); 1635 eastPane = c; 1636 } 1637 1638 /** 1639 * This method returns the east pane. 1640 * 1641 * @return The east pane. 1642 */ 1643 public JComponent getEastPane() 1644 { 1645 return eastPane; 1646 } 1647 1648 /** 1649 * This method sets the west pane to be the given JComponent. 1650 * 1651 * @param c The new west pane. 1652 */ 1653 public void setWestPane(JComponent c) 1654 { 1655 replacePane(westPane, c); 1656 westPane = c; 1657 } 1658 1659 /** 1660 * This method returns the west pane. 1661 * 1662 * @return The west pane. 1663 */ 1664 public JComponent getWestPane() 1665 { 1666 return westPane; 1667 } 1668 1669 /** 1670 * This method returns the DesktopManager to use with the JInternalFrame. 1671 * 1672 * @return The DesktopManager to use with the JInternalFrame. 1673 */ 1674 protected DesktopManager getDesktopManager() 1675 { 1676 DesktopManager value = null; 1677 JDesktopPane pane = frame.getDesktopPane(); 1678 if (pane != null) 1679 value = frame.getDesktopPane().getDesktopManager(); 1680 if (value == null) 1681 value = createDesktopManager(); 1682 return value; 1683 } 1684 1685 /** 1686 * This method returns a default DesktopManager that can be used with this 1687 * JInternalFrame. 1688 * 1689 * @return A default DesktopManager that can be used with this 1690 * JInternalFrame. 1691 */ 1692 protected DesktopManager createDesktopManager() 1693 { 1694 return new DefaultDesktopManager(); 1695 } 1696 1697 /** 1698 * This is a convenience method that closes the JInternalFrame. 1699 * 1700 * @param f The JInternalFrame to close. 1701 */ 1702 protected void closeFrame(JInternalFrame f) 1703 { 1704 getDesktopManager().closeFrame(f); 1705 } 1706 1707 /** 1708 * This is a convenience method that maximizes the JInternalFrame. 1709 * 1710 * @param f The JInternalFrame to maximize. 1711 */ 1712 protected void maximizeFrame(JInternalFrame f) 1713 { 1714 getDesktopManager().maximizeFrame(f); 1715 } 1716 1717 /** 1718 * This is a convenience method that minimizes the JInternalFrame. 1719 * 1720 * @param f The JInternalFrame to minimize. 1721 */ 1722 protected void minimizeFrame(JInternalFrame f) 1723 { 1724 getDesktopManager().minimizeFrame(f); 1725 } 1726 1727 /** 1728 * This is a convenience method that iconifies the JInternalFrame. 1729 * 1730 * @param f The JInternalFrame to iconify. 1731 */ 1732 protected void iconifyFrame(JInternalFrame f) 1733 { 1734 getDesktopManager().iconifyFrame(f); 1735 } 1736 1737 /** 1738 * This is a convenience method that deiconifies the JInternalFrame. 1739 * 1740 * @param f The JInternalFrame to deiconify. 1741 */ 1742 protected void deiconifyFrame(JInternalFrame f) 1743 { 1744 getDesktopManager().deiconifyFrame(f); 1745 } 1746 1747 /** 1748 * This is a convenience method that activates the JInternalFrame. 1749 * 1750 * @param f The JInternalFrame to activate. 1751 */ 1752 protected void activateFrame(JInternalFrame f) 1753 { 1754 getDesktopManager().activateFrame(f); 1755 } 1756 1757 /** 1758 * This is a convenience method that deactivates the JInternalFrame. 1759 * 1760 * @param f the JInternalFrame to deactivate 1761 */ 1762 protected void deactivateFrame(JInternalFrame f) 1763 { 1764 getDesktopManager().deactivateFrame(f); 1765 } 1766 1767 /** 1768 * This method returns a new ComponentListener for the JDesktopPane. 1769 * 1770 * @return A new ComponentListener. 1771 */ 1772 protected ComponentListener createComponentListener() 1773 { 1774 return new ComponentHandler(); 1775 } 1776 1777 /** 1778 * This method returns a new GlassPaneDispatcher. 1779 * 1780 * @return A new GlassPaneDispatcher. 1781 */ 1782 protected MouseInputListener createGlassPaneDispatcher() 1783 { 1784 return new GlassPaneDispatcher(); 1785 } 1786 }