Source for javax.swing.plaf.basic.BasicInternalFrameUI

   1: /* BasicInternalFrameUI.java --
   2:    Copyright (C) 2004, 2005 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.AWTEvent;
  42: import java.awt.Color;
  43: import java.awt.Component;
  44: import java.awt.Container;
  45: import java.awt.Dimension;
  46: import java.awt.Graphics;
  47: import java.awt.Insets;
  48: import java.awt.LayoutManager;
  49: import java.awt.Point;
  50: import java.awt.Rectangle;
  51: import java.awt.event.ComponentEvent;
  52: import java.awt.event.ComponentListener;
  53: import java.awt.event.MouseEvent;
  54: import java.beans.PropertyChangeEvent;
  55: import java.beans.PropertyChangeListener;
  56: import java.beans.PropertyVetoException;
  57: import java.beans.VetoableChangeListener;
  58: 
  59: import javax.swing.DefaultDesktopManager;
  60: import javax.swing.DesktopManager;
  61: import javax.swing.JComponent;
  62: import javax.swing.JDesktopPane;
  63: import javax.swing.JInternalFrame;
  64: import javax.swing.KeyStroke;
  65: import javax.swing.LookAndFeel;
  66: import javax.swing.SwingConstants;
  67: import javax.swing.SwingUtilities;
  68: import javax.swing.UIManager;
  69: import javax.swing.border.AbstractBorder;
  70: import javax.swing.event.InternalFrameEvent;
  71: import javax.swing.event.InternalFrameListener;
  72: import javax.swing.event.MouseInputAdapter;
  73: import javax.swing.event.MouseInputListener;
  74: import javax.swing.plaf.ComponentUI;
  75: import javax.swing.plaf.InternalFrameUI;
  76: import javax.swing.plaf.UIResource;
  77: 
  78: /**
  79:  * This is the UI delegate for the Basic look and feel for JInternalFrames.
  80:  */
  81: public class BasicInternalFrameUI extends InternalFrameUI
  82: {
  83:   /**
  84:    * This is a helper class that listens to the JInternalFrame for
  85:    * InternalFrameEvents.
  86:    */
  87:   protected class BasicInternalFrameListener implements InternalFrameListener
  88:   {
  89:     /**
  90:      * This method is called when the JInternalFrame is activated.
  91:      *
  92:      * @param e The InternalFrameEvent.
  93:      */
  94:     public void internalFrameActivated(InternalFrameEvent e)
  95:     {
  96:       // FIXME: Implement.
  97:     }
  98: 
  99:     /**
 100:      * This method is called when the JInternalFrame is closed.
 101:      *
 102:      * @param e The InternalFrameEvent.
 103:      */
 104:     public void internalFrameClosed(InternalFrameEvent e)
 105:     {
 106:       // FIXME: Implement.
 107:     }
 108: 
 109:     /**
 110:      * This method is called when the JInternalFrame is closing.
 111:      *
 112:      * @param e The InternalFrameEvent.
 113:      */
 114:     public void internalFrameClosing(InternalFrameEvent e)
 115:     {
 116:       // FIXME: Implement.
 117:     }
 118: 
 119:     /**
 120:      * This method is called when the JInternalFrame is deactivated.
 121:      *
 122:      * @param e The InternalFrameEvent.
 123:      */
 124:     public void internalFrameDeactivated(InternalFrameEvent e)
 125:     {
 126:       // FIXME: Implement.
 127:     }
 128: 
 129:     /**
 130:      * This method is called when the JInternalFrame is  deiconified.
 131:      *
 132:      * @param e The InternalFrameEvent.
 133:      */
 134:     public void internalFrameDeiconified(InternalFrameEvent e)
 135:     {
 136:       // FIXME: Implement.
 137:     }
 138: 
 139:     /**
 140:      * This method is called when the JInternalFrame is  iconified.
 141:      *
 142:      * @param e The InternalFrameEvent.
 143:      */
 144:     public void internalFrameIconified(InternalFrameEvent e)
 145:     {
 146:       // FIXME: Implement.
 147:     }
 148: 
 149:     /**
 150:      * This method is called when the JInternalFrame is opened.
 151:      *
 152:      * @param e The InternalFrameEvent.
 153:      */
 154:     public void internalFrameOpened(InternalFrameEvent e)
 155:     {
 156:       // FIXME: Implement.
 157:     }
 158:   }
 159: 
 160:   /**
 161:    * This helper class listens to the edges of the JInternalFrame and the
 162:    * TitlePane for mouse events. It is responsible for dragging  and resizing
 163:    * the JInternalFrame in response to the MouseEvents.
 164:    */
 165:   protected class BorderListener extends MouseInputAdapter
 166:     implements SwingConstants
 167:   {
 168:     /** FIXME: Use for something. */
 169:     protected final int RESIZE_NONE = 0;
 170: 
 171:     /** The x offset from the top left corner of the JInternalFrame. */
 172:     private transient int xOffset = 0;
 173: 
 174:     /** The y offset from the top left corner of the JInternalFrame. */
 175:     private transient int yOffset = 0;
 176: 
 177:     /** The direction that the resize is occuring in. */
 178:     private transient int direction = -1;
 179: 
 180:     /** Cache rectangle that can be reused. */
 181:     private transient Rectangle cacheRect = new Rectangle();
 182: 
 183:     /**
 184:      * This method is called when the mouse is clicked.
 185:      *
 186:      * @param e The MouseEvent.
 187:      */
 188:     public void mouseClicked(MouseEvent e)
 189:     {
 190:       // There is nothing to do when the mouse is clicked
 191:       // on the border.
 192:     }
 193: 
 194:     /**
 195:      * This method is called when the mouse is dragged. This method is
 196:      * responsible for resizing or dragging the JInternalFrame.
 197:      *
 198:      * @param e The MouseEvent.
 199:      */
 200:     public void mouseDragged(MouseEvent e)
 201:     {
 202:       // If the frame is maximized, there is nothing that
 203:       // can be dragged around.
 204:       if (frame.isMaximum())
 205:         return;
 206:       DesktopManager dm = getDesktopManager();
 207:       Rectangle b = frame.getBounds();
 208:       Dimension min = frame.getMinimumSize();
 209:       if (min == null)
 210:         min = new Dimension(0, 0);
 211:       Insets insets = frame.getInsets();
 212:       int x = e.getX();
 213:       int y = e.getY();
 214:       if (e.getSource() == frame && frame.isResizable())
 215:         {
 216:           switch (direction)
 217:             {
 218:             case NORTH:
 219:               cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
 220:                                                          - min.height),
 221:                                   b.width, b.height - y);
 222:               break;
 223:             case NORTH_EAST:
 224:               cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
 225:                                                          - min.height), x,
 226:                                   b.height - y);
 227:               break;
 228:             case EAST:
 229:               cacheRect.setBounds(b.x, b.y, x, b.height);
 230:               break;
 231:             case SOUTH_EAST:
 232:               cacheRect.setBounds(b.x, b.y, x, y);
 233:               break;
 234:             case SOUTH:
 235:               cacheRect.setBounds(b.x, b.y, b.width, y);
 236:               break;
 237:             case SOUTH_WEST:
 238:               cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
 239:                                   b.y, b.width - x, y);
 240:               break;
 241:             case WEST:
 242:               cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
 243:                                   b.y, b.width - x, b.height);
 244:               break;
 245:             case NORTH_WEST:
 246:               cacheRect.setBounds(
 247:                                   Math.min(b.x + x, b.x + b.width - min.width),
 248:                                   Math.min(b.y + y, b.y + b.height - min.height),
 249:                                   b.width - x, b.height - y);
 250:               break;
 251:             }
 252:           dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
 253:                          Math.max(min.width, cacheRect.width),
 254:                          Math.max(min.height, cacheRect.height));
 255:         }
 256:       else if (e.getSource() == titlePane)
 257:         {
 258:           Rectangle fBounds = frame.getBounds();
 259: 
 260:           dm.dragFrame(frame, e.getX() - xOffset + b.x, e.getY() - yOffset
 261:                                                         + b.y);
 262:         }
 263:     }
 264: 
 265:     /**
 266:      * This method is called when the mouse exits the JInternalFrame.
 267:      *
 268:      * @param e The MouseEvent.
 269:      */
 270:     public void mouseExited(MouseEvent e)
 271:     {
 272:       // There is nothing to do when the mouse exits 
 273:       // the border area.
 274:     }
 275: 
 276:     /**
 277:      * This method is called when the mouse is moved inside the
 278:      * JInternalFrame.
 279:      *
 280:      * @param e The MouseEvent.
 281:      */
 282:     public void mouseMoved(MouseEvent e)
 283:     {
 284:       // There is nothing to do when the mouse moves
 285:       // over the border area.
 286:     }
 287: 
 288:     /**
 289:      * This method is called when the mouse is pressed.
 290:      *
 291:      * @param e The MouseEvent.
 292:      */
 293:     public void mousePressed(MouseEvent e)
 294:     {
 295:       activateFrame(frame);
 296:       DesktopManager dm = getDesktopManager();
 297:       int x = e.getX();
 298:       int y = e.getY();
 299:       Insets insets = frame.getInsets();
 300: 
 301:       if (e.getSource() == frame && frame.isResizable())
 302:         {
 303:           direction = sectionOfClick(x, y);
 304:           dm.beginResizingFrame(frame, direction);
 305:         }
 306:       else if (e.getSource() == titlePane)
 307:         {
 308:           Rectangle tBounds = titlePane.getBounds();
 309: 
 310:           xOffset = e.getX() - tBounds.x + insets.left;
 311:           yOffset = e.getY() - tBounds.y + insets.top;
 312: 
 313:           dm.beginDraggingFrame(frame);
 314:         }
 315:     }
 316: 
 317:     /**
 318:      * This method is called when the mouse is released.
 319:      *
 320:      * @param e The MouseEvent.
 321:      */
 322:     public void mouseReleased(MouseEvent e)
 323:     {
 324:       DesktopManager dm = getDesktopManager();
 325:       xOffset = 0;
 326:       yOffset = 0;
 327:       if (e.getSource() == frame && frame.isResizable())
 328:         dm.endResizingFrame(frame);
 329:       else if (e.getSource() == titlePane)
 330:         dm.endDraggingFrame(frame);
 331:     }
 332: 
 333:     /**
 334:      * This method determines the direction of the resize based on the
 335:      * coordinates and the size of the JInternalFrame.
 336:      *
 337:      * @param x The x coordinate of the MouseEvent.
 338:      * @param y The y coordinate of the MouseEvent.
 339:      *
 340:      * @return The direction of the resize (a SwingConstant direction).
 341:      */
 342:     private int sectionOfClick(int x, int y)
 343:     {
 344:       Insets insets = frame.getInsets();
 345:       Rectangle b = frame.getBounds();
 346:       if (x < insets.left && y < insets.top)
 347:         return NORTH_WEST;
 348:       else if (x > b.width - insets.right && y < insets.top)
 349:         return NORTH_EAST;
 350:       else if (x > b.width - insets.right && y > b.height - insets.bottom)
 351:         return SOUTH_EAST;
 352:       else if (x < insets.left && y > b.height - insets.bottom)
 353:         return SOUTH_WEST;
 354:       else if (y < insets.top)
 355:         return NORTH;
 356:       else if (x < insets.left)
 357:         return WEST;
 358:       else if (y > b.height - insets.bottom)
 359:         return SOUTH;
 360:       else if (x > b.width - insets.right)
 361:         return EAST;
 362: 
 363:       return -1;
 364:     }
 365:   }
 366: 
 367:   /**
 368:    * This helper class listens to the JDesktopPane that parents this
 369:    * JInternalFrame and listens for resize events and resizes the
 370:    * JInternalFrame appropriately.
 371:    */
 372:   protected class ComponentHandler implements ComponentListener
 373:   {
 374:     /**
 375:      * This method is called when the JDesktopPane is hidden.
 376:      * 
 377:      * @param e
 378:      *          The ComponentEvent fired.
 379:      */
 380:     public void componentHidden(ComponentEvent e)
 381:     {
 382:       // Do nothing.
 383:     }
 384: 
 385:     /**
 386:      * This method is called when the JDesktopPane is moved.
 387:      * 
 388:      * @param e
 389:      *          The ComponentEvent fired.
 390:      */
 391:     public void componentMoved(ComponentEvent e)
 392:     {
 393:       // Do nothing.
 394:     }
 395: 
 396:     /**
 397:      * This method is called when the JDesktopPane is resized.
 398:      * 
 399:      * @param e
 400:      *          The ComponentEvent fired.
 401:      */
 402:     public void componentResized(ComponentEvent e)
 403:     {
 404:       if (frame.isMaximum())
 405:         {
 406:           JDesktopPane pane = (JDesktopPane) e.getSource();
 407:           Insets insets = pane.getInsets();
 408:           Rectangle bounds = pane.getBounds();
 409: 
 410:           frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
 411:                           bounds.width - insets.left - insets.right,
 412:                           bounds.height - insets.top - insets.bottom);
 413:           frame.revalidate();
 414:           frame.repaint();
 415:         }
 416: 
 417:       // Sun also resizes the icons. but it doesn't seem to do anything.
 418:     }
 419: 
 420:     /**
 421:      * This method is called when the JDesktopPane is shown.
 422:      * 
 423:      * @param e
 424:      *          The ComponentEvent fired.
 425:      */
 426:     public void componentShown(ComponentEvent e)
 427:     {
 428:       // Do nothing.
 429:     }
 430:   }
 431: 
 432:   /**
 433:    * This helper class acts as the LayoutManager for JInternalFrames.
 434:    */
 435:   public class InternalFrameLayout implements LayoutManager
 436:   {
 437:     /**
 438:      * This method is called when the given Component is added to the
 439:      * JInternalFrame.
 440:      * 
 441:      * @param name
 442:      *          The name of the Component.
 443:      * @param c
 444:      *          The Component added.
 445:      */
 446:     public void addLayoutComponent(String name, Component c)
 447:     {
 448:       // Nothing to do here.
 449:     }
 450: 
 451:     /**
 452:      * This method is used to set the bounds of the children of the
 453:      * JInternalFrame.
 454:      * 
 455:      * @param c
 456:      *          The Container to lay out.
 457:      */
 458:     public void layoutContainer(Container c)
 459:     {
 460:       Dimension dims = frame.getSize();
 461:       Insets insets = frame.getInsets();
 462: 
 463:       dims.width -= insets.left + insets.right;
 464:       dims.height -= insets.top + insets.bottom;
 465: 
 466:       frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
 467:                                                    dims.height);
 468:       int nh = 0;
 469:       int sh = 0;
 470:       int ew = 0;
 471:       int ww = 0;
 472: 
 473:       if (northPane != null)
 474:         {
 475:           Dimension nDims = northPane.getPreferredSize();
 476:           nh = Math.min(nDims.height, dims.height);
 477: 
 478:           northPane.setBounds(insets.left, insets.top, dims.width, nh);
 479:         }
 480: 
 481:       if (southPane != null)
 482:         {
 483:           Dimension sDims = southPane.getPreferredSize();
 484:           sh = Math.min(sDims.height, dims.height - nh);
 485: 
 486:           southPane.setBounds(insets.left, insets.top + dims.height - sh,
 487:                               dims.width, sh);
 488:         }
 489: 
 490:       int remHeight = dims.height - sh - nh;
 491: 
 492:       if (westPane != null)
 493:         {
 494:           Dimension wDims = westPane.getPreferredSize();
 495:           ww = Math.min(dims.width, wDims.width);
 496: 
 497:           westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
 498:         }
 499: 
 500:       if (eastPane != null)
 501:         {
 502:           Dimension eDims = eastPane.getPreferredSize();
 503:           ew = Math.min(eDims.width, dims.width - ww);
 504: 
 505:           eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
 506:                              ew, remHeight);
 507:         }
 508: 
 509:       int remWidth = dims.width - ww - ew;
 510: 
 511:       frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
 512:                                     remWidth, remHeight);
 513:     }
 514: 
 515:     /**
 516:      * This method returns the minimum layout size.
 517:      * 
 518:      * @param c
 519:      *          The Container to find a minimum layout size for.
 520:      * @return The minimum dimensions for the JInternalFrame.
 521:      */
 522:     public Dimension minimumLayoutSize(Container c)
 523:     {
 524:       return getSize(c, true);
 525:     }
 526: 
 527:     /**
 528:      * This method returns the maximum layout size.
 529:      * 
 530:      * @param c
 531:      *          The Container to find a maximum layout size for.
 532:      * @return The maximum dimensions for the JInternalFrame.
 533:      */
 534:     public Dimension maximumLayoutSize(Container c)
 535:     {
 536:       return preferredLayoutSize(c);
 537:     }
 538: 
 539:     /**
 540:      * Th8is method returns the preferred layout size.
 541:      * 
 542:      * @param c
 543:      *          The Container to find a preferred layout size for.
 544:      * @return The preferred dimensions for the JInternalFrame.
 545:      */
 546:     public Dimension preferredLayoutSize(Container c)
 547:     {
 548:       return getSize(c, false);
 549:     }
 550: 
 551:     /**
 552:      * DOCUMENT ME!
 553:      * 
 554:      * @param c
 555:      *          DOCUMENT ME!
 556:      * @param min
 557:      *          DOCUMENT ME!
 558:      * @return DOCUMENT ME!
 559:      */
 560:     private Dimension getSize(Container c, boolean min)
 561:     {
 562:       Insets insets = frame.getInsets();
 563: 
 564:       Dimension contentDims = frame.getContentPane().getPreferredSize();
 565:       if (min)
 566:         contentDims.width = contentDims.height = 0;
 567:       int nWidth = 0;
 568:       int nHeight = 0;
 569:       int sWidth = 0;
 570:       int sHeight = 0;
 571:       int eWidth = 0;
 572:       int eHeight = 0;
 573:       int wWidth = 0;
 574:       int wHeight = 0;
 575:       Dimension dims;
 576: 
 577:       if (northPane != null)
 578:         {
 579:           dims = northPane.getPreferredSize();
 580:           if (dims != null)
 581:             {
 582:               nWidth = dims.width;
 583:               nHeight = dims.height;
 584:             }
 585:         }
 586: 
 587:       if (southPane != null)
 588:         {
 589:           dims = southPane.getPreferredSize();
 590:           if (dims != null)
 591:             {
 592:               sWidth = dims.width;
 593:               sHeight = dims.height;
 594:             }
 595:         }
 596: 
 597:       if (eastPane != null)
 598:         {
 599:           dims = eastPane.getPreferredSize();
 600:           if (dims != null)
 601:             {
 602:               sWidth = dims.width;
 603:               sHeight = dims.height;
 604:             }
 605:         }
 606: 
 607:       if (westPane != null)
 608:         {
 609:           dims = westPane.getPreferredSize();
 610:           if (dims != null)
 611:             {
 612:               wWidth = dims.width;
 613:               wHeight = dims.height;
 614:             }
 615:         }
 616: 
 617:       int width = Math.max(sWidth, nWidth);
 618:       width = Math.max(width, contentDims.width + eWidth + wWidth);
 619: 
 620:       int height = Math.max(eHeight, wHeight);
 621:       height = Math.max(height, contentDims.height);
 622:       height += nHeight + sHeight;
 623: 
 624:       width += insets.left + insets.right;
 625:       height += insets.top + insets.bottom;
 626: 
 627:       return new Dimension(width, height);
 628:     }
 629: 
 630:     /**
 631:      * This method is called when a Component is removed from the
 632:      * JInternalFrame.
 633:      *
 634:      * @param c The Component that was removed.
 635:      */
 636:     public void removeLayoutComponent(Component c)
 637:     {
 638:       // Nothing to do here.
 639:     }
 640:   }
 641: 
 642:   /**
 643:    * This helper class is used to listen to the JDesktopPane's glassPane for
 644:    * MouseEvents. The JInternalFrame can then be selected if a click is
 645:    * detected on its children.
 646:    */
 647:   protected class GlassPaneDispatcher implements MouseInputListener
 648:   {
 649:     /** The MouseEvent target. */
 650:     private transient Component mouseEventTarget;
 651: 
 652:     /** The component pressed. */
 653:     private transient Component pressedComponent;
 654: 
 655:     /** The last component entered. */
 656:     private transient Component lastComponentEntered;
 657: 
 658:     /** Used to store/reset lastComponentEntered. */
 659:     private transient Component tempComponent;
 660: 
 661:     /** The number of presses. */
 662:     private transient int pressCount;
 663: 
 664:     /**
 665:      * This method is called when the mouse enters the glass pane.
 666:      * 
 667:      * @param e
 668:      *          The MouseEvent.
 669:      */
 670:     public void mouseEntered(MouseEvent e)
 671:     {
 672:       handleEvent(e);
 673:     }
 674: 
 675:     /**
 676:      * This method is called when the mouse is clicked on the glass pane.
 677:      * 
 678:      * @param e
 679:      *          The MouseEvent.
 680:      */
 681:     public void mouseClicked(MouseEvent e)
 682:     {
 683:       handleEvent(e);
 684:     }
 685: 
 686:     /**
 687:      * This method is called when the mouse is dragged in the glass pane.
 688:      * 
 689:      * @param e
 690:      *          The MouseEvent.
 691:      */
 692:     public void mouseDragged(MouseEvent e)
 693:     {
 694:       handleEvent(e);
 695:     }
 696: 
 697:     /**
 698:      * This method is called when the mouse exits the glass pane.
 699:      * 
 700:      * @param e
 701:      *          The MouseEvent.
 702:      */
 703:     public void mouseExited(MouseEvent e)
 704:     {
 705:       handleEvent(e);
 706:     }
 707: 
 708:     /**
 709:      * This method is called when the mouse is moved in the glass pane.
 710:      * 
 711:      * @param e
 712:      *          The MouseEvent.
 713:      */
 714:     public void mouseMoved(MouseEvent e)
 715:     {
 716:       handleEvent(e);
 717:     }
 718: 
 719:     /**
 720:      * This method is called when the mouse is pressed in the glass pane.
 721:      * 
 722:      * @param e
 723:      *          The MouseEvent.
 724:      */
 725:     public void mousePressed(MouseEvent e)
 726:     {
 727:       activateFrame(frame);
 728:       handleEvent(e);
 729:     }
 730: 
 731:     /**
 732:      * This method is called when the mouse is released in the glass pane.
 733:      * 
 734:      * @param e
 735:      *          The MouseEvent.
 736:      */
 737:     public void mouseReleased(MouseEvent e)
 738:     {
 739:       handleEvent(e);
 740:     }
 741: 
 742:     /**
 743:      * This method acquires a candidate component to dispatch the MouseEvent to.
 744:      * 
 745:      * @param me
 746:      *          The MouseEvent to acquire a component for.
 747:      */
 748:     private void acquireComponentForMouseEvent(MouseEvent me)
 749:     {
 750:       int x = me.getX();
 751:       int y = me.getY();
 752: 
 753:       // Find the candidate which should receive this event.
 754:       Component parent = frame.getLayeredPane();
 755:       if (parent == null)
 756:         return;
 757:       Component candidate = null;
 758:       Point p = me.getPoint();
 759:       while (candidate == null && parent != null)
 760:         {
 761:           candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
 762:           if (candidate == null)
 763:             {
 764:               p = SwingUtilities.convertPoint(parent, p.x, p.y,
 765:                                               parent.getParent());
 766:               parent = parent.getParent();
 767:             }
 768:         }
 769: 
 770:       // If the only candidate we found was the native container itself,
 771:       // don't dispatch any event at all. We only care about the lightweight
 772:       // children here.
 773:       if (candidate == frame.getContentPane())
 774:         candidate = null;
 775: 
 776:       // If our candidate is new, inform the old target we're leaving.
 777:       if (lastComponentEntered != null && lastComponentEntered.isShowing()
 778:           && lastComponentEntered != candidate)
 779:         {
 780:           Point tp = SwingUtilities.convertPoint(frame.getContentPane(), x, y,
 781:                                                  lastComponentEntered);
 782:           MouseEvent exited = new MouseEvent(lastComponentEntered,
 783:                                              MouseEvent.MOUSE_EXITED,
 784:                                              me.getWhen(), me.getModifiersEx(),
 785:                                              tp.x, tp.y, me.getClickCount(),
 786:                                              me.isPopupTrigger(),
 787:                                              me.getButton());
 788:           tempComponent = lastComponentEntered;
 789:           lastComponentEntered = null;
 790:           tempComponent.dispatchEvent(exited);
 791:         }
 792: 
 793:       // If we have a candidate, maybe enter it.
 794:       if (candidate != null)
 795:         {
 796:           mouseEventTarget = candidate;
 797:           if (candidate.isLightweight() && candidate.isShowing()
 798:               && candidate != frame.getContentPane()
 799:               && candidate != lastComponentEntered)
 800:             {
 801:               lastComponentEntered = mouseEventTarget;
 802:               Point cp = SwingUtilities.convertPoint(frame.getContentPane(), x,
 803:                                                      y, lastComponentEntered);
 804:               MouseEvent entered = new MouseEvent(lastComponentEntered,
 805:                                                   MouseEvent.MOUSE_ENTERED,
 806:                                                   me.getWhen(),
 807:                                                   me.getModifiersEx(), cp.x,
 808:                                                   cp.y, me.getClickCount(),
 809:                                                   me.isPopupTrigger(),
 810:                                                   me.getButton());
 811:               lastComponentEntered.dispatchEvent(entered);
 812:             }
 813:         }
 814: 
 815:       if (me.getID() == MouseEvent.MOUSE_RELEASED
 816:           || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
 817:           || me.getID() == MouseEvent.MOUSE_DRAGGED)
 818:         // If any of the following events occur while a button is held down,
 819:         // they should be dispatched to the same component to which the
 820:         // original MOUSE_PRESSED event was dispatched:
 821:         // - MOUSE_RELEASED
 822:         // - MOUSE_PRESSED: another button pressed while the first is held down
 823:         // - MOUSE_DRAGGED
 824:         mouseEventTarget = pressedComponent;
 825:       else if (me.getID() == MouseEvent.MOUSE_CLICKED)
 826:         {
 827:           // Don't dispatch CLICKED events whose target is not the same as the
 828:           // target for the original PRESSED event.
 829:           if (candidate != pressedComponent)
 830:             mouseEventTarget = null;
 831:           else if (pressCount == 0)
 832:             pressedComponent = null;
 833:         }
 834:     }
 835: 
 836:     /**
 837:      * This is a helper method that dispatches the GlassPane MouseEvents to the
 838:      * proper component.
 839:      * 
 840:      * @param e
 841:      *          The AWTEvent to be dispatched. Usually an instance of
 842:      *          MouseEvent.
 843:      */
 844:     private void handleEvent(AWTEvent e)
 845:     {
 846:       if (e instanceof MouseEvent)
 847:         {
 848:           MouseEvent me = (MouseEvent) e;
 849:           acquireComponentForMouseEvent(me);
 850: 
 851:           //If there is no target, return
 852:           if (mouseEventTarget == null)
 853:             return;
 854:           
 855:           //Avoid re-dispatching to ourselves and causing an infinite loop
 856:           if (mouseEventTarget.equals(frame.getGlassPane()))
 857:             return;
 858: 
 859:           // Avoid dispatching ENTERED and EXITED events twice.
 860:           if (mouseEventTarget.isShowing()
 861:               && e.getID() != MouseEvent.MOUSE_ENTERED
 862:               && e.getID() != MouseEvent.MOUSE_EXITED)
 863:             {
 864:               MouseEvent newEvt = SwingUtilities.convertMouseEvent(
 865:                                                                    frame.getGlassPane(),
 866:                                                                    me,
 867:                                                                    mouseEventTarget);
 868:               mouseEventTarget.dispatchEvent(newEvt);
 869: 
 870:               switch (e.getID())
 871:                 {
 872:                 case MouseEvent.MOUSE_PRESSED:
 873:                   if (pressCount++ == 0)
 874:                     pressedComponent = mouseEventTarget;
 875:                   break;
 876:                 case MouseEvent.MOUSE_RELEASED:
 877:                   // Clear our memory of the original PRESSED event, only if
 878:                   // we're not expecting a CLICKED event after this. If
 879:                   // there is a CLICKED event after this, it will do clean up.
 880:                   if (--pressCount == 0 && mouseEventTarget != pressedComponent)
 881:                     pressedComponent = null;
 882:                   break;
 883:                 }
 884:             }
 885:         }
 886:     }
 887:   }
 888: 
 889:   /**
 890:    * This helper class listens for PropertyChangeEvents from the
 891:    * JInternalFrame.
 892:    */
 893:   public class InternalFramePropertyChangeListener implements
 894:       PropertyChangeListener, VetoableChangeListener
 895:   {
 896: 
 897:     /**
 898:      * This method is called when one of the JInternalFrame's properties change.
 899:      * This method is to allow JInternalFrame to veto an attempt to close the
 900:      * internal frame. This allows JInternalFrame to honour its
 901:      * defaultCloseOperation if that is DO_NOTHING_ON_CLOSE.
 902:      */
 903:     public void vetoableChange(PropertyChangeEvent e)
 904:         throws PropertyVetoException
 905:     {
 906:       if (e.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
 907:         {
 908:           if (frame.getDefaultCloseOperation() == JInternalFrame.HIDE_ON_CLOSE)
 909:             {
 910:               frame.setVisible(false);
 911:               frame.getDesktopPane().repaint();
 912:               throw new PropertyVetoException(
 913:                                               "close operation is HIDE_ON_CLOSE\n",
 914:                                               e);
 915:             }
 916:           else if (frame.getDefaultCloseOperation() == JInternalFrame.DISPOSE_ON_CLOSE)
 917:             closeFrame(frame);
 918:           else
 919:             throw new PropertyVetoException(
 920:                                             "close operation is DO_NOTHING_ON_CLOSE\n",
 921:                                             e);
 922:         }
 923:     }
 924: 
 925:     /**
 926:      * This method is called when one of the JInternalFrame's properties change.
 927:      * 
 928:      * @param evt
 929:      *          The PropertyChangeEvent.
 930:      */
 931:     public void propertyChange(PropertyChangeEvent evt)
 932:     {
 933:       if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
 934:         {
 935:           if (frame.isMaximum())
 936:             maximizeFrame(frame);
 937:           else
 938:             minimizeFrame(frame);
 939:         }
 940:       else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
 941:         {
 942:           if (frame.isIcon())
 943:             iconifyFrame(frame);
 944:           else
 945:             deiconifyFrame(frame);
 946:         }
 947:       else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
 948:         {
 949:           if (frame.isSelected())
 950:             activateFrame(frame);
 951:           else
 952:             deactivateFrame(frame);
 953:         }
 954:       else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
 955:                || evt.getPropertyName().equals(
 956:                                                JInternalFrame.GLASS_PANE_PROPERTY))
 957:         {
 958:           Component old = (Component) evt.getOldValue();
 959:           old.removeMouseListener(glassPaneDispatcher);
 960:           old.removeMouseMotionListener(glassPaneDispatcher);
 961: 
 962:           Component newPane = (Component) evt.getNewValue();
 963:           newPane.addMouseListener(glassPaneDispatcher);
 964:           newPane.addMouseMotionListener(glassPaneDispatcher);
 965: 
 966:           frame.revalidate();
 967:         }
 968:       /*
 969:        * FIXME: need to add ancestor properties to JComponents. else if
 970:        * (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY)) { if
 971:        * (desktopPane != null)
 972:        * desktopPane.removeComponentListener(componentListener); desktopPane =
 973:        * frame.getDesktopPane(); if (desktopPane != null)
 974:        * desktopPane.addComponentListener(componentListener); }
 975:        */
 976:     }
 977:   }
 978: 
 979:   /**
 980:    * This helper class is the border for the JInternalFrame.
 981:    */
 982:   private class InternalFrameBorder extends AbstractBorder implements
 983:       UIResource
 984:   {
 985:     /** The width of the border. */
 986:     private static final int bSize = 5;
 987: 
 988:     /** The size of the corners. */
 989:     private static final int offset = 10;
 990: 
 991:     /**
 992:      * This method returns whether the border is opaque.
 993:      * 
 994:      * @return Whether the border is opaque.
 995:      */
 996:     public boolean isBorderOpaque()
 997:     {
 998:       return true;
 999:     }
1000: 
1001:     /**
1002:      * This method returns the insets of the border.
1003:      * 
1004:      * @param c
1005:      *          The Component to find border insets for.
1006:      * @return The border insets.
1007:      */
1008:     public Insets getBorderInsets(Component c)
1009:     {
1010:       return new Insets(bSize, bSize, bSize, bSize);
1011:     }
1012: 
1013:     /**
1014:      * This method paints the border.
1015:      * 
1016:      * @param c
1017:      *          The Component that owns the border.
1018:      * @param g
1019:      *          The Graphics object to paint with.
1020:      * @param x
1021:      *          The x coordinate to paint at.
1022:      * @param y
1023:      *          The y coordinate to paint at.
1024:      * @param width
1025:      *          The width of the Component.
1026:      * @param height
1027:      *          The height of the Component.
1028:      */
1029:     public void paintBorder(Component c, Graphics g, int x, int y, int width,
1030:                             int height)
1031:     {
1032:       g.translate(x, y);
1033:       Color saved = g.getColor();
1034:       Rectangle b = frame.getBounds();
1035: 
1036:       Color d = c.getBackground();
1037:       g.setColor(d);
1038:       g.fillRect(0, 0, bSize, b.height);
1039:       g.fillRect(0, 0, b.width, bSize);
1040:       g.fillRect(0, b.height - bSize, b.width, bSize);
1041:       g.fillRect(b.width - bSize, 0, bSize, b.height);
1042: 
1043:       int x1 = 0;
1044:       int x2 = bSize;
1045:       int x3 = b.width - bSize;
1046:       int x4 = b.width;
1047: 
1048:       int y1 = 0;
1049:       int y2 = bSize;
1050:       int y3 = b.height - bSize;
1051:       int y4 = b.height;
1052: 
1053:       g.setColor(Color.GRAY);
1054:       g.fillRect(0, 0, bSize, y4);
1055:       g.fillRect(0, 0, x4, bSize);
1056:       g.fillRect(0, y3, b.width, bSize);
1057:       g.fillRect(x3, 0, bSize, b.height);
1058: 
1059:       g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
1060:       g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
1061:       g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
1062:       g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
1063: 
1064:       g.translate(-x, -y);
1065:       g.setColor(saved);
1066:     }
1067:   }
1068: 
1069:   /**
1070:    * The MouseListener that is responsible for dragging and resizing the
1071:    * JInternalFrame in response to MouseEvents.
1072:    */
1073:   protected MouseInputAdapter borderListener;
1074: 
1075:   /**
1076:    * The ComponentListener that is responsible for resizing the JInternalFrame
1077:    * in response to ComponentEvents from the JDesktopPane.
1078:    */
1079:   protected ComponentListener componentListener;
1080: 
1081:   /**
1082:    * The MouseListener that is responsible for activating the JInternalFrame
1083:    * when the mouse press activates one of its descendents.
1084:    */
1085:   protected MouseInputListener glassPaneDispatcher;
1086: 
1087:   /**
1088:    * The PropertyChangeListener that is responsible for listening to
1089:    * PropertyChangeEvents from the JInternalFrame.
1090:    */
1091:   protected PropertyChangeListener propertyChangeListener;
1092: 
1093:   /**
1094:    * The VetoableChangeListener.  Listens to PropertyChangeEvents
1095:    * from the JInternalFrame and allows the JInternalFrame to 
1096:    * veto attempts to close it.
1097:    */
1098:   private VetoableChangeListener internalFrameVetoableChangeListener;
1099: 
1100:   /** The InternalFrameListener that listens to the JInternalFrame. */
1101:   private transient BasicInternalFrameListener internalFrameListener;
1102: 
1103:   /** The JComponent placed at the east region of the JInternalFrame. */
1104:   protected JComponent eastPane;
1105: 
1106:   /** The JComponent placed at the north region of the JInternalFrame. */
1107:   protected JComponent northPane;
1108: 
1109:   /** The JComponent placed at the south region of the JInternalFrame. */
1110:   protected JComponent southPane;
1111: 
1112:   /** The JComponent placed at the west region of the JInternalFrame. */
1113:   protected JComponent westPane;
1114: 
1115:   /**
1116:    * The Keystroke bound to open the menu.
1117:    * @deprecated
1118:    */
1119:   protected KeyStroke openMenuKey;
1120: 
1121:   /** The TitlePane displayed at the top of the JInternalFrame. */
1122:   protected BasicInternalFrameTitlePane titlePane;
1123: 
1124:   /** The JInternalFrame this UI is responsible for. */
1125:   protected JInternalFrame frame;
1126: 
1127:   /** The LayoutManager used in the JInternalFrame. */
1128:   protected LayoutManager internalFrameLayout;
1129: 
1130:   /** The JDesktopPane that is the parent of the JInternalFrame. */
1131:   private transient JDesktopPane desktopPane;
1132: 
1133:   /**
1134:    * Creates a new BasicInternalFrameUI object.
1135:    *
1136:    * @param b The JInternalFrame this UI will represent.
1137:    */
1138:   public BasicInternalFrameUI(JInternalFrame b)
1139:   {
1140:     // Nothing to do here.
1141:   }
1142: 
1143:   /**
1144:    * This method will create a new BasicInternalFrameUI for the given
1145:    * JComponent.
1146:    *
1147:    * @param b The JComponent to create a BasicInternalFrameUI for.
1148:    *
1149:    * @return A new BasicInternalFrameUI.
1150:    */
1151:   public static ComponentUI createUI(JComponent b)
1152:   {
1153:     return new BasicInternalFrameUI((JInternalFrame) b);
1154:   }
1155: 
1156:   /**
1157:    * This method installs a UI for the JInternalFrame.
1158:    *
1159:    * @param c The JComponent to install this UI on.
1160:    */
1161:   public void installUI(JComponent c)
1162:   {
1163:     if (c instanceof JInternalFrame)
1164:       {
1165:         frame = (JInternalFrame) c;
1166: 
1167:         internalFrameLayout = createLayoutManager();
1168:         frame.setLayout(internalFrameLayout);
1169: 
1170:         ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
1171:         frame.getRootPane().getGlassPane().setVisible(true);
1172: 
1173:         installDefaults();
1174:         installListeners();
1175:         installComponents();
1176:         installKeyboardActions();
1177: 
1178:         frame.setOpaque(true);
1179:         frame.invalidate();
1180:       }
1181:   }
1182: 
1183:   /**
1184:    * This method reverses the work done by installUI.
1185:    *
1186:    * @param c The JComponent to uninstall this UI for.
1187:    */
1188:   public void uninstallUI(JComponent c)
1189:   {
1190:     uninstallKeyboardActions();
1191:     uninstallComponents();
1192:     uninstallListeners();
1193:     uninstallDefaults();
1194: 
1195:     frame.setLayout(null);
1196:     ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
1197:     frame.getRootPane().getGlassPane().setVisible(false);
1198: 
1199:     frame = null;
1200:   }
1201: 
1202:   /**
1203:    * This method installs the defaults specified by the look and feel.
1204:    */
1205:   protected void installDefaults()
1206:     {
1207:       LookAndFeel.installBorder(frame, "InternalFrame.border");
1208:       frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
1209:       // InternalFrames are invisible by default.
1210:       frame.setVisible(false);
1211:   }
1212: 
1213:   /**
1214:    * This method installs the keyboard actions for the JInternalFrame.
1215:    */
1216:   protected void installKeyboardActions()
1217:   {
1218:     // FIXME: Implement.
1219:   }
1220: 
1221:   /**
1222:    * This method installs the Components for the JInternalFrame.
1223:    */
1224:   protected void installComponents()
1225:   {
1226:     setNorthPane(createNorthPane(frame));
1227:     setSouthPane(createSouthPane(frame));
1228:     setEastPane(createEastPane(frame));
1229:     setWestPane(createWestPane(frame));
1230:   }
1231: 
1232:   /**
1233:    * This method installs the listeners for the JInternalFrame.
1234:    */
1235:   protected void installListeners()
1236:   {
1237:     glassPaneDispatcher = createGlassPaneDispatcher();
1238:     createInternalFrameListener();
1239:     borderListener = createBorderListener(frame);
1240:     componentListener = createComponentListener();
1241:     propertyChangeListener = createPropertyChangeListener();
1242:     internalFrameVetoableChangeListener = new InternalFramePropertyChangeListener();
1243: 
1244:     frame.addMouseListener(borderListener);
1245:     frame.addMouseMotionListener(borderListener);
1246:     frame.addInternalFrameListener(internalFrameListener);
1247:     frame.addPropertyChangeListener(propertyChangeListener);
1248:     frame.addVetoableChangeListener(internalFrameVetoableChangeListener);
1249:     frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
1250:     frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
1251:   }
1252: 
1253:   /**
1254:    * This method uninstalls the defaults for the JInternalFrame.
1255:    */
1256:   protected void uninstallDefaults()
1257:   {
1258:     frame.setBorder(null);
1259:   }
1260: 
1261:   /**
1262:    * This method uninstalls the Components for the JInternalFrame.
1263:    */
1264:   protected void uninstallComponents()
1265:   {
1266:     setNorthPane(null);
1267:     setSouthPane(null);
1268:     setEastPane(null);
1269:     setWestPane(null);
1270:   }
1271: 
1272:   /**
1273:    * This method uninstalls the listeners for the JInternalFrame.
1274:    */
1275:   protected void uninstallListeners()
1276:   {
1277:     if (desktopPane != null)
1278:       desktopPane.removeComponentListener(componentListener);
1279: 
1280:     frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
1281:     frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
1282: 
1283:     frame.removePropertyChangeListener(propertyChangeListener);
1284:     frame.removeInternalFrameListener(internalFrameListener);
1285:     frame.removeMouseMotionListener(borderListener);
1286:     frame.removeMouseListener(borderListener);
1287: 
1288:     propertyChangeListener = null;
1289:     componentListener = null;
1290:     borderListener = null;
1291:     internalFrameListener = null;
1292:     glassPaneDispatcher = null;
1293:   }
1294: 
1295:   /**
1296:    * This method uninstalls the keyboard actions for the JInternalFrame.
1297:    */
1298:   protected void uninstallKeyboardActions()
1299:   {
1300:     // FIXME: Implement.
1301:   }
1302: 
1303:   /**
1304:    * This method creates a new LayoutManager for the JInternalFrame.
1305:    *
1306:    * @return A new LayoutManager for the JInternalFrame.
1307:    */
1308:   protected LayoutManager createLayoutManager()
1309:   {
1310:     return new InternalFrameLayout();
1311:   }
1312: 
1313:   /**
1314:    * This method creates a new PropertyChangeListener for the JInternalFrame.
1315:    *
1316:    * @return A new PropertyChangeListener for the JInternalFrame.
1317:    */
1318:   protected PropertyChangeListener createPropertyChangeListener()
1319:   {
1320:     return new InternalFramePropertyChangeListener();
1321:   }
1322: 
1323:   /**
1324:    * This method returns the preferred size of the given JComponent.
1325:    *
1326:    * @param x The JComponent to find a preferred size for.
1327:    *
1328:    * @return The preferred size.
1329:    */
1330:   public Dimension getPreferredSize(JComponent x)
1331:   {
1332:     return internalFrameLayout.preferredLayoutSize(x);
1333:   }
1334: 
1335:   /**
1336:    * This method returns the minimum size of the given JComponent.
1337:    *
1338:    * @param x The JComponent to find a minimum size for.
1339:    *
1340:    * @return The minimum size.
1341:    */
1342:   public Dimension getMinimumSize(JComponent x)
1343:   {
1344:     return internalFrameLayout.minimumLayoutSize(x);
1345:   }
1346: 
1347:   /**
1348:    * This method returns the maximum size of the given JComponent.
1349:    *
1350:    * @param x The JComponent to find a maximum size for.
1351:    *
1352:    * @return The maximum size.
1353:    */
1354:   public Dimension getMaximumSize(JComponent x)
1355:   {
1356:     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1357:   }
1358: 
1359:   /**
1360:    * This method replaces the currentPane with the newPane. When replacing it
1361:    * also removes the MouseHandlers for the old pane and installs  them on
1362:    * the new pane.
1363:    *
1364:    * @param currentPane The old pane to remove.
1365:    * @param newPane The new pane to install.
1366:    */
1367:   protected void replacePane(JComponent currentPane, JComponent newPane)
1368:   {
1369:     if (currentPane != null)
1370:       {
1371:         deinstallMouseHandlers(currentPane);
1372:         frame.remove(currentPane);
1373:       }
1374: 
1375:     if (newPane != null)
1376:       {
1377:         installMouseHandlers(newPane);
1378:         frame.add(newPane);
1379:       }
1380:   }
1381: 
1382:   /**
1383:    * This method removes the necessary MouseListeners from the given
1384:    * JComponent.
1385:    *
1386:    * @param c The JComponent to remove MouseListeners from.
1387:    */
1388:   protected void deinstallMouseHandlers(JComponent c)
1389:   {
1390:     c.removeMouseListener(borderListener);
1391:     c.removeMouseMotionListener(borderListener);
1392:   }
1393: 
1394:   /**
1395:    * This method installs the necessary MouseListeners from the given
1396:    * JComponent.
1397:    *
1398:    * @param c The JComponent to install MouseListeners on.
1399:    */
1400:   protected void installMouseHandlers(JComponent c)
1401:   {
1402:     c.addMouseListener(borderListener);
1403:     c.addMouseMotionListener(borderListener);
1404:   }
1405: 
1406:   /**
1407:    * This method creates the north pane used in the JInternalFrame.
1408:    *
1409:    * @param w The JInternalFrame to create a north pane for.
1410:    *
1411:    * @return The north pane.
1412:    */
1413:   protected JComponent createNorthPane(JInternalFrame w)
1414:   {
1415:     titlePane = new BasicInternalFrameTitlePane(w);
1416:     return titlePane;
1417:   }
1418: 
1419:   /**
1420:    * This method creates the west pane used in the JInternalFrame.
1421:    *
1422:    * @param w The JInternalFrame to create a west pane for.
1423:    *
1424:    * @return The west pane.
1425:    */
1426:   protected JComponent createWestPane(JInternalFrame w)
1427:   {
1428:     return null;
1429:   }
1430: 
1431:   /**
1432:    * This method creates the south pane used in the JInternalFrame.
1433:    *
1434:    * @param w The JInternalFrame to create a south pane for.
1435:    *
1436:    * @return The south pane.
1437:    */
1438:   protected JComponent createSouthPane(JInternalFrame w)
1439:   {
1440:     return null;
1441:   }
1442: 
1443:   /**
1444:    * This method creates the east pane used in the JInternalFrame.
1445:    *
1446:    * @param w The JInternalFrame to create an east pane for.
1447:    *
1448:    * @return The east pane.
1449:    */
1450:   protected JComponent createEastPane(JInternalFrame w)
1451:   {
1452:     return null;
1453:   }
1454: 
1455:   /**
1456:    * This method returns a new BorderListener for the given JInternalFrame.
1457:    *
1458:    * @param w The JIntenalFrame to create a BorderListener for.
1459:    *
1460:    * @return A new BorderListener.
1461:    */
1462:   protected MouseInputAdapter createBorderListener(JInternalFrame w)
1463:   {
1464:     return new BorderListener();
1465:   }
1466: 
1467:   /**
1468:    * This method creates a new InternalFrameListener for the JInternalFrame.
1469:    */
1470:   protected void createInternalFrameListener()
1471:   {
1472:     internalFrameListener = new BasicInternalFrameListener();
1473:   }
1474: 
1475:   /**
1476:    * DOCUMENT ME!
1477:    *
1478:    * @return DOCUMENT ME!
1479:    */
1480:   protected final boolean isKeyBindingRegistered()
1481:   {
1482:     // FIXME: Implement.
1483:     return false;
1484:   }
1485: 
1486:   /**
1487:    * DOCUMENT ME!
1488:    *
1489:    * @param b DOCUMENT ME!
1490:    */
1491:   protected final void setKeyBindingRegistered(boolean b)
1492:   {
1493:     // FIXME: Implement.
1494:   }
1495: 
1496:   /**
1497:    * DOCUMENT ME!
1498:    *
1499:    * @return DOCUMENT ME!
1500:    */
1501:   public final boolean isKeyBindingActive()
1502:   {
1503:     // FIXME: Implement.
1504:     return false;
1505:   }
1506: 
1507:   /**
1508:    * DOCUMENT ME!
1509:    *
1510:    * @param b DOCUMENT ME!
1511:    */
1512:   protected final void setKeyBindingActive(boolean b)
1513:   {
1514:     // FIXME: Implement.
1515:   }
1516: 
1517:   /**
1518:    * DOCUMENT ME!
1519:    */
1520:   protected void setupMenuOpenKey()
1521:   {
1522:     // FIXME: Implement.
1523:   }
1524: 
1525:   /**
1526:    * DOCUMENT ME!
1527:    */
1528:   protected void setupMenuCloseKey()
1529:   {
1530:     // FIXME: Implement.
1531:   }
1532: 
1533:   /**
1534:    * This method returns the north pane.
1535:    *
1536:    * @return The north pane.
1537:    */
1538:   public JComponent getNorthPane()
1539:   {
1540:     return northPane;
1541:   }
1542: 
1543:   /**
1544:    * This method sets the north pane to be the given JComponent.
1545:    *
1546:    * @param c The new north pane.
1547:    */
1548:   public void setNorthPane(JComponent c)
1549:   {
1550:     replacePane(northPane, c);
1551:     northPane = c;
1552:   }
1553: 
1554:   /**
1555:    * This method returns the south pane.
1556:    *
1557:    * @return The south pane.
1558:    */
1559:   public JComponent getSouthPane()
1560:   {
1561:     return southPane;
1562:   }
1563: 
1564:   /**
1565:    * This method sets the south pane to be the given JComponent.
1566:    *
1567:    * @param c The new south pane.
1568:    */
1569:   public void setSouthPane(JComponent c)
1570:   {
1571:     replacePane(southPane, c);
1572:     southPane = c;
1573:   }
1574: 
1575:   /**
1576:    * This method sets the east pane to be the given JComponent.
1577:    *
1578:    * @param c The new east pane.
1579:    */
1580:   public void setEastPane(JComponent c)
1581:   {
1582:     replacePane(eastPane, c);
1583:     eastPane = c;
1584:   }
1585: 
1586:   /**
1587:    * This method returns the east pane.
1588:    *
1589:    * @return The east pane.
1590:    */
1591:   public JComponent getEastPane()
1592:   {
1593:     return eastPane;
1594:   }
1595: 
1596:   /**
1597:    * This method sets the west pane to be the given JComponent.
1598:    *
1599:    * @param c The new west pane.
1600:    */
1601:   public void setWestPane(JComponent c)
1602:   {
1603:     replacePane(westPane, c);
1604:     westPane = c;
1605:   }
1606: 
1607:   /**
1608:    * This method returns the west pane.
1609:    *
1610:    * @return The west pane.
1611:    */
1612:   public JComponent getWestPane()
1613:   {
1614:     return westPane;
1615:   }
1616: 
1617:   /**
1618:    * This method returns the DesktopManager to use with the JInternalFrame.
1619:    *
1620:    * @return The DesktopManager to use with the JInternalFrame.
1621:    */
1622:   protected DesktopManager getDesktopManager()
1623:   {
1624:     DesktopManager value = null;
1625:     JDesktopPane pane = frame.getDesktopPane();
1626:     if (pane != null)
1627:       value = frame.getDesktopPane().getDesktopManager();
1628:     if (value == null)
1629:       value = createDesktopManager();
1630:     return value;
1631:   }
1632: 
1633:   /**
1634:    * This method returns a default DesktopManager that can be used with this
1635:    * JInternalFrame.
1636:    *
1637:    * @return A default DesktopManager that can be used with this
1638:    *         JInternalFrame.
1639:    */
1640:   protected DesktopManager createDesktopManager()
1641:   {
1642:     return new DefaultDesktopManager();
1643:   }
1644: 
1645:   /**
1646:    * This is a convenience method that closes the JInternalFrame.
1647:    *
1648:    * @param f The JInternalFrame to close.
1649:    */
1650:   protected void closeFrame(JInternalFrame f)
1651:   {
1652:     getDesktopManager().closeFrame(f);
1653:   }
1654: 
1655:   /**
1656:    * This is a convenience method that maximizes the JInternalFrame.
1657:    *
1658:    * @param f The JInternalFrame to maximize.
1659:    */
1660:   protected void maximizeFrame(JInternalFrame f)
1661:   {
1662:     getDesktopManager().maximizeFrame(f);
1663:   }
1664: 
1665:   /**
1666:    * This is a convenience method that minimizes the JInternalFrame.
1667:    *
1668:    * @param f The JInternalFrame to minimize.
1669:    */
1670:   protected void minimizeFrame(JInternalFrame f)
1671:   {
1672:     getDesktopManager().minimizeFrame(f);
1673:   }
1674: 
1675:   /**
1676:    * This is a convenience method that iconifies the JInternalFrame.
1677:    *
1678:    * @param f The JInternalFrame to iconify.
1679:    */
1680:   protected void iconifyFrame(JInternalFrame f)
1681:   {
1682:     getDesktopManager().iconifyFrame(f);
1683:   }
1684: 
1685:   /**
1686:    * This is a convenience method that deiconifies the JInternalFrame.
1687:    *
1688:    * @param f The JInternalFrame to deiconify.
1689:    */
1690:   protected void deiconifyFrame(JInternalFrame f)
1691:   {
1692:     getDesktopManager().deiconifyFrame(f);
1693:   }
1694: 
1695:   /**
1696:    * This is a convenience method that activates the JInternalFrame.
1697:    *
1698:    * @param f The JInternalFrame to activate.
1699:    */
1700:   protected void activateFrame(JInternalFrame f)
1701:   {
1702:     getDesktopManager().activateFrame(f);
1703:   }
1704: 
1705:   /**
1706:    * This is a convenience method that deactivates the JInternalFrame.
1707:    *
1708:    * @param f the JInternalFrame to deactivate
1709:    */
1710:   protected void deactivateFrame(JInternalFrame f)
1711:   {
1712:     getDesktopManager().deactivateFrame(f);
1713:   }
1714: 
1715:   /**
1716:    * This method returns a new ComponentListener for the JDesktopPane.
1717:    *
1718:    * @return A new ComponentListener.
1719:    */
1720:   protected ComponentListener createComponentListener()
1721:   {
1722:     return new ComponentHandler();
1723:   }
1724: 
1725:   /**
1726:    * This method returns a new GlassPaneDispatcher.
1727:    *
1728:    * @return A new GlassPaneDispatcher.
1729:    */
1730:   protected MouseInputListener createGlassPaneDispatcher()
1731:   {
1732:     return new GlassPaneDispatcher();
1733:   }
1734: }