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