1: /* BasicInternalFrameUI.java -- 2: Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.plaf.basic; 40: 41: import java.awt.Color; 42: import java.awt.Component; 43: import java.awt.Container; 44: import java.awt.Cursor; 45: import java.awt.Dimension; 46: import java.awt.Graphics; 47: import java.awt.Insets; 48: import java.awt.LayoutManager; 49: import java.awt.LayoutManager2; 50: import java.awt.Point; 51: import java.awt.Rectangle; 52: import java.awt.event.ActionEvent; 53: import java.awt.event.ComponentEvent; 54: import java.awt.event.ComponentListener; 55: import java.awt.event.MouseEvent; 56: import java.beans.PropertyChangeEvent; 57: import java.beans.PropertyChangeListener; 58: import java.beans.PropertyVetoException; 59: 60: import javax.swing.AbstractAction; 61: import javax.swing.ActionMap; 62: import javax.swing.DefaultDesktopManager; 63: import javax.swing.DesktopManager; 64: import javax.swing.JComponent; 65: import javax.swing.JDesktopPane; 66: import javax.swing.JInternalFrame; 67: import javax.swing.KeyStroke; 68: import javax.swing.LookAndFeel; 69: import javax.swing.SwingConstants; 70: import javax.swing.SwingUtilities; 71: import javax.swing.UIManager; 72: import javax.swing.border.AbstractBorder; 73: import javax.swing.event.InternalFrameEvent; 74: import javax.swing.event.InternalFrameListener; 75: import javax.swing.event.MouseInputAdapter; 76: import javax.swing.event.MouseInputListener; 77: import javax.swing.plaf.ActionMapUIResource; 78: import javax.swing.plaf.ComponentUI; 79: import javax.swing.plaf.InternalFrameUI; 80: import javax.swing.plaf.UIResource; 81: 82: /** 83: * This is the UI delegate for the Basic look and feel for JInternalFrames. 84: */ 85: public class BasicInternalFrameUI extends InternalFrameUI 86: { 87: /** 88: * This is a helper class that listens to the JInternalFrame for 89: * InternalFrameEvents. 90: */ 91: protected class BasicInternalFrameListener implements InternalFrameListener 92: { 93: /** 94: * This method is called when the JInternalFrame is activated. 95: * 96: * @param e The InternalFrameEvent. 97: */ 98: public void internalFrameActivated(InternalFrameEvent e) 99: { 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: }