Source for gnu.java.awt.peer.swing.SwingComponentPeer

   1: /* SwingComponentPeer.java -- An abstract base class for Swing based peers
   2:    Copyright (C)  2006  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.java.awt.peer.swing;
  39: 
  40: import java.awt.AWTEvent;
  41: import java.awt.AWTException;
  42: import java.awt.BufferCapabilities;
  43: import java.awt.Color;
  44: import java.awt.Component;
  45: import java.awt.Cursor;
  46: import java.awt.Dimension;
  47: import java.awt.Font;
  48: import java.awt.FontMetrics;
  49: import java.awt.Graphics;
  50: import java.awt.GraphicsConfiguration;
  51: import java.awt.Image;
  52: import java.awt.Point;
  53: import java.awt.Rectangle;
  54: import java.awt.Toolkit;
  55: import java.awt.BufferCapabilities.FlipContents;
  56: import java.awt.event.KeyEvent;
  57: import java.awt.event.MouseEvent;
  58: import java.awt.event.PaintEvent;
  59: import java.awt.image.ColorModel;
  60: import java.awt.image.ImageObserver;
  61: import java.awt.image.ImageProducer;
  62: import java.awt.image.VolatileImage;
  63: import java.awt.peer.ComponentPeer;
  64: import java.awt.peer.ContainerPeer;
  65: 
  66: /**
  67:  * The base class for Swing based component peers. This provides the basic
  68:  * functionality needed for Swing based component peers. Many methods are
  69:  * implemented to forward to the Swing component. Others however forward
  70:  * to the component's parent and expect the toplevel component peer to provide
  71:  * a real implementation of it. These are for example the key methods
  72:  * {@link #getGraphics()} and {@link #createImage(int, int)}, as well as
  73:  * {@link #getLocationOnScreen()}.
  74:  *
  75:  * This class also provides the necesary hooks into the Swing painting and
  76:  * event handling system. In order to achieve this, it traps paint, mouse and
  77:  * key events in {@link #handleEvent(AWTEvent)} and calls some special methods
  78:  * ({@link #peerPaint(Graphics)}, {@link #handleKeyEvent(KeyEvent)},
  79:  * {@link #handleMouseEvent(MouseEvent)} and
  80:  * {@link #handleMouseMotionEvent(MouseEvent)}) that call the corresponding
  81:  * Swing methods.
  82:  *
  83:  * @author Roman Kennke (kennke@aicas.com)
  84:  */
  85: public class SwingComponentPeer
  86:   implements ComponentPeer
  87: {
  88: 
  89:   /**
  90:    * The AWT component for this peer.
  91:    */
  92:   protected Component awtComponent;
  93: 
  94:   /**
  95:    * The Swing component for this peer.
  96:    */
  97:   protected SwingComponent swingComponent;
  98: 
  99:   /**
 100:    * Creates a SwingComponentPeer instance. Subclasses are expected to call
 101:    * this constructor and thereafter call
 102:    * {@link #init(Component,SwingComponent)}
 103:    * in order to setup the AWT and Swing components properly.
 104:    */
 105:   protected SwingComponentPeer()
 106:   {
 107:     // Nothing to do here.
 108:   }
 109: 
 110:   /**
 111:    * Initializes the AWT and Swing component for this peer. It is expected that
 112:    * subclasses call this from within their constructor.
 113:    *
 114:    * @param awtComp the AWT component for this peer
 115:    * @param swingComp the Swing component for this peer
 116:    */
 117:   protected void init(Component awtComp, SwingComponent swingComp)
 118:   {
 119:     awtComponent = awtComp;
 120:     swingComponent = swingComp;
 121:   }
 122: 
 123:   /**
 124:    * Returns the construction status of the specified image. This is called
 125:    * by {@link Component#checkImage(Image, int, int, ImageObserver)}.
 126:    *
 127:    * @param img the image
 128:    * @param width the width of the image
 129:    * @param height the height of the image
 130:    * @param ob the image observer to be notified of updates of the status
 131:    *
 132:    * @return a bitwise ORed set of ImageObserver flags
 133:    */
 134:   public int checkImage(Image img, int width, int height, ImageObserver ob)
 135:   {
 136:     return Toolkit.getDefaultToolkit().checkImage(img, width, height, ob);
 137:   }
 138: 
 139:   /**
 140:    * Creates an image by starting the specified image producer. This is called
 141:    * by {@link Component#createImage(ImageProducer)}.
 142:    *
 143:    * @param prod the image producer to be used to create the image
 144:    *
 145:    * @return the created image
 146:    */
 147:   public Image createImage(ImageProducer prod)
 148:   {
 149:     Image image = Toolkit.getDefaultToolkit().createImage(prod);
 150:     return image;
 151:   }
 152: 
 153:   /**
 154:    * Creates an empty image with the specified <code>width</code> and
 155:    * <code>height</code>.
 156:    *
 157:    * This is implemented to let the parent component create the image. This
 158:    * eventually goes up to the top-level component peer, which is then expected
 159:    * to deliver the image.
 160:    *
 161:    * @param width the width of the image to be created
 162:    * @param height the height of the image to be created
 163:    *
 164:    * @return the created image
 165:    */
 166:   public Image createImage(int width, int height)
 167:   {
 168:     Component parent = awtComponent.getParent();
 169:     ComponentPeer parentPeer = parent.getPeer();
 170:     return parentPeer.createImage(width, height);
 171:   }
 172: 
 173:   /**
 174:    * Disables the component. This is called by {@link Component#disable()}.
 175:    */
 176:   public void disable()
 177:   {
 178:     if (swingComponent != null)
 179:       swingComponent.getJComponent().setEnabled(false);
 180:   }
 181: 
 182:   /**
 183:    * Disposes the component peer. This should release all resources held by the
 184:    * peer. This is called when the component is no longer in use.
 185:    */
 186:   public void dispose()
 187:   {
 188:     awtComponent = null;
 189:     swingComponent = null;
 190:   }
 191: 
 192:   /**
 193:    * Enables the component. This is called by {@link Component#enable()}.
 194:    */
 195:   public void enable()
 196:   {
 197:     if (swingComponent != null)
 198:       swingComponent.getJComponent().setEnabled(true);
 199:   }
 200: 
 201:   /**
 202:    * Returns the color model of the component. This is currently not used.
 203:    *
 204:    * @return the color model of the component
 205:    */
 206:   public ColorModel getColorModel()
 207:   {
 208:     // FIXME: When this peer method will be used, we need to provide an
 209:     // implementation of this, probably forwarding to the toplevel peer, like
 210:     // in the other methods.
 211:     return null;
 212:   }
 213: 
 214:   /**
 215:    * Returns the font metrics for the specified font. This is called by
 216:    * {@link Component#getFontMetrics(Font)}.
 217:    *
 218:    * This is implemented to query the font metrics from the parent component.
 219:    * This will eventually call the top-level component peer, which is then
 220:    * expected to deliver a font metrics object.
 221:    *
 222:    * @param f the font for which to query the font metrics
 223:    *
 224:    * @return the font metrics for the specified font
 225:    */
 226:   public FontMetrics getFontMetrics(Font f)
 227:   {
 228:     Component parent = awtComponent.getParent();
 229:     ComponentPeer parentPeer = parent.getPeer();
 230:     return parentPeer.getFontMetrics(f);
 231:   }
 232: 
 233:   /**
 234:    * Returns a {@link Graphics} object suitable for drawing on this component.
 235:    * This is called by {@link Component#getGraphics()}.
 236:    *
 237:    * This is implemented to query the graphics from the parent component and
 238:    * adjust the clip and translation to match this component.
 239:    * This will eventually call the top-level component peer, which is then
 240:    * expected to deliver a graphics object.
 241:    *
 242:    * @return a graphics object suitable for drawing on this component
 243:    */
 244:   public Graphics getGraphics()
 245:   {
 246:     Component parent = awtComponent.getParent();
 247:     ComponentPeer parentPeer = parent.getPeer();
 248:     Graphics g = parentPeer.getGraphics();
 249:     g.translate(awtComponent.getX(), awtComponent.getY());
 250:     g.setClip(0, 0, awtComponent.getWidth(), awtComponent.getHeight());
 251:     return g;
 252:   }
 253: 
 254:   /**
 255:    * Returns the location of this component in screen coordinates. This is
 256:    * called by {@link Component#getLocationOnScreen()}.
 257:    *
 258:    * This is implemented to query the parent component peer for its screen
 259:    * location and adds the offset of this component to it. This will eventually
 260:    * call the top-level component's peer, which is then expected to provide
 261:    * it's screen location.
 262:    *
 263:    * @return the location of this component in screen coordinates
 264:    */
 265:   public Point getLocationOnScreen()
 266:   {
 267:     Component parent = awtComponent.getParent();
 268:     ComponentPeer parentPeer = parent.getPeer();
 269:     Point location = parentPeer.getLocationOnScreen();
 270:     location.x += awtComponent.getX();
 271:     location.y += awtComponent.getY();
 272:     return location;
 273:   }
 274: 
 275:   /**
 276:    * Returns the minimum size for the component. This is called by
 277:    * {@link Component#getMinimumSize()}.
 278:    *
 279:    * This is implemented to return the Swing component's minimum size.
 280:    *
 281:    * @return the minimum size for the component
 282:    */
 283:   public Dimension getMinimumSize()
 284:   {
 285:     Dimension retVal;
 286:     if (swingComponent != null)
 287:       retVal = swingComponent.getJComponent().getMinimumSize();
 288:     else
 289:       retVal = new Dimension(0, 0);
 290:     return retVal;
 291:   }
 292: 
 293:   /**
 294:    * Returns the preferred size for the component. This is called by
 295:    * {@link Component#getPreferredSize()}.
 296:    *
 297:    * This is implemented to return the Swing component's preferred size.
 298:    *
 299:    * @return the preferred size for the component
 300:    */
 301:   public Dimension getPreferredSize()
 302:   {
 303:     Dimension retVal;
 304:     if (swingComponent != null)
 305:       retVal = swingComponent.getJComponent().getPreferredSize();
 306:     else
 307:       retVal = new Dimension(0, 0);
 308:     return retVal;
 309:   }
 310: 
 311:   /**
 312:    * Returns the toolkit that created this peer.
 313:    *
 314:    * @return the toolkit that created this peer
 315:    */
 316:   public Toolkit getToolkit()
 317:   {
 318:     return Toolkit.getDefaultToolkit();
 319:   }
 320: 
 321:   /**
 322:    * Handles the given event. This is called from
 323:    * {@link Component#dispatchEvent(AWTEvent)} to give the peer a chance to 
 324:    * react to events for the component.
 325:    *
 326:    * @param e the event
 327:    */
 328:   public void handleEvent(AWTEvent e)
 329:   {
 330:     switch (e.getID())
 331:     {
 332:       case PaintEvent.UPDATE:
 333:       case PaintEvent.PAINT:
 334:         // This only will work when the component is showing.
 335:         if (awtComponent.isShowing())
 336:           {
 337:             Graphics g = getGraphics();
 338:             Rectangle clip = ((PaintEvent)e).getUpdateRect();
 339:             g.clipRect(clip.x, clip.y, clip.width, clip.height);
 340:             //if (this instanceof LightweightPeer)
 341:             //  {
 342:             if (e.getID() == PaintEvent.UPDATE)
 343:               awtComponent.update(g);
 344:             else
 345:               awtComponent.paint(g);
 346:             //  }
 347:             // We paint the 'heavyweights' at last, so that they appear on top of
 348:             // everything else.
 349:             peerPaint(g);
 350:             g.dispose();
 351:           }
 352:         break;
 353:       case MouseEvent.MOUSE_PRESSED:
 354:       case MouseEvent.MOUSE_RELEASED:
 355:       case MouseEvent.MOUSE_CLICKED:
 356:       case MouseEvent.MOUSE_ENTERED:
 357:       case MouseEvent.MOUSE_EXITED:
 358:         handleMouseEvent((MouseEvent) e);
 359:         break;
 360:       case MouseEvent.MOUSE_MOVED:
 361:       case MouseEvent.MOUSE_DRAGGED:
 362:         handleMouseMotionEvent((MouseEvent) e);
 363:         break;
 364:       case KeyEvent.KEY_PRESSED:
 365:       case KeyEvent.KEY_RELEASED:
 366:       case KeyEvent.KEY_TYPED:
 367:         handleKeyEvent((KeyEvent) e);
 368:         break;
 369:       default:
 370:         // Other event types are not handled here.
 371:         break;
 372:     }
 373:   }
 374: 
 375:   /**
 376:    * Makes the component invisible. This is called from
 377:    * {@link Component#hide()}.
 378:    *
 379:    * This is implemented to call setVisible(false) on the Swing component.
 380:    */
 381:   public void hide()
 382:   {
 383:     if (swingComponent != null)
 384:       swingComponent.getJComponent().setVisible(false);
 385: 
 386:     Component parent = awtComponent.getParent();
 387:     if (parent != null)
 388:       parent.repaint(awtComponent.getX(), awtComponent.getY(),
 389:                      awtComponent.getWidth(), awtComponent.getHeight());
 390:   }
 391: 
 392:   /**
 393:    * Returns <code>true</code> if the component can receive keyboard input
 394:    * focus. This is called from {@link Component#isFocusTraversable()}.
 395:    * 
 396:    * This is implemented to return isFocusable() from the Swing component.
 397:    *
 398:    * @specnote Part of the earlier 1.1 API, replaced by isFocusable().
 399:    */
 400:   public boolean isFocusTraversable()
 401:   {
 402:     return swingComponent != null ?
 403:              swingComponent.getJComponent().isFocusable() : false;
 404:   }
 405: 
 406:   /**
 407:    * Returns <code>true</code> if the component can receive keyboard input
 408:    * focus. This is called from {@link Component#isFocusable()}.
 409:    *
 410:    * This is implemented to return isFocusable() from the Swing component.
 411:    */
 412:   public boolean isFocusable()
 413:   {
 414:     return swingComponent != null ?
 415:              swingComponent.getJComponent().isFocusable() : false;
 416:   }
 417: 
 418:   /**
 419:    * Returns the minimum size for the component. This is called by
 420:    * {@link Component#minimumSize()}.
 421:    *
 422:    * This is implemented to return the Swing component's minimum size.
 423:    *
 424:    * @return the minimum size for the component
 425:    */
 426:   public Dimension minimumSize()
 427:   {
 428:     Dimension retVal;
 429:     if (swingComponent != null)
 430:       retVal = swingComponent.getJComponent().getMinimumSize();
 431:     else
 432:       retVal = new Dimension(0, 0);
 433:     return retVal;
 434:   }
 435: 
 436:   /**
 437:    * Returns the preferred size for the component. This is called by
 438:    * {@link Component#getPreferredSize()}.
 439:    *
 440:    * This is implemented to return the Swing component's preferred size.
 441:    *
 442:    * @return the preferred size for the component
 443:    */
 444:   public Dimension preferredSize()
 445:   {
 446:     Dimension retVal;
 447:     if (swingComponent != null)
 448:       retVal = swingComponent.getJComponent().getPreferredSize();
 449:     else
 450:       retVal = new Dimension(0, 0);
 451:     return retVal;
 452:   }
 453: 
 454:   public void paint(Graphics graphics)
 455:   {
 456:     // FIXME: I don't know what this method is supposed to do.
 457:   }
 458: 
 459:   /**
 460:    * Prepares an image for rendering on this component. This is called by
 461:    * {@link Component#prepareImage(Image, int, int, ImageObserver)}.
 462:    *
 463:    * @param img the image to prepare
 464:    * @param width the desired width of the rendered image
 465:    * @param height the desired height of the rendered image
 466:    * @param ob the image observer to be notified of updates in the preparation
 467:    *        process
 468:    *
 469:    * @return <code>true</code> if the image has been fully prepared,
 470:    *         <code>false</code> otherwise (in which case the image observer
 471:    *         receives updates)
 472:    */
 473:   public boolean prepareImage(Image img, int width, int height, ImageObserver ob)
 474:   {
 475:     Component parent = awtComponent.getParent();
 476:     if(parent != null)
 477:     {
 478:       ComponentPeer parentPeer = parent.getPeer();
 479:       return parentPeer.prepareImage(img, width, height, ob);
 480:     }
 481:     else
 482:     {
 483:       return Toolkit.getDefaultToolkit().prepareImage(img, width, height, ob);
 484:     }
 485:   }
 486: 
 487:   public void print(Graphics graphics)
 488:   {
 489:     // FIXME: I don't know what this method is supposed to do.
 490:   }
 491: 
 492:   /**
 493:    * Repaints the specified rectangle of this component. This is called from
 494:    * {@link Component#repaint(long, int, int, int, int)}.
 495:    *
 496:    * This is implemented to call repaint() on the Swing component.
 497:    *
 498:    * @param tm number of milliseconds to wait with repainting
 499:    * @param x the X coordinate of the upper left corner of the damaged rectangle
 500:    * @param y the Y coordinate of the upper left corner of the damaged rectangle
 501:    * @param width the width of the damaged rectangle
 502:    * @param height the height of the damaged rectangle
 503:    */
 504:   public void repaint(long tm, int x, int y, int width, int height)
 505:   {
 506:     if (swingComponent != null)
 507:       swingComponent.getJComponent().repaint(tm, x, y, width, height);
 508:     else
 509:       {
 510:         PaintEvent ev = new PaintEvent(awtComponent, PaintEvent.UPDATE,
 511:                                        new Rectangle(x, y, width, height));
 512:         Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ev);
 513:       }
 514:   }
 515: 
 516:   /**
 517:    * Requests that this component receives the focus. This is called from
 518:    * {@link Component#requestFocus()}.
 519:    * 
 520:    * This calls requestFocus() on the Swing component.
 521:    *
 522:    * @specnote Part of the earlier 1.1 API, apparently replaced by argument 
 523:    *           form of the same method.
 524:    */
 525:   public void requestFocus()
 526:   {
 527:     if (swingComponent != null)
 528:       swingComponent.getJComponent().requestFocus();
 529:   }
 530: 
 531:   /**
 532:    * Requests that this component receives the focus. This is called from
 533:    * {@link Component#requestFocus()}.
 534:    *
 535:    * This calls requestFocus() on the Swing component.
 536:    *
 537:    * @param source TODO
 538:    * @param bool1 TODO
 539:    * @param bool2 TODO
 540:    * @param x TODO
 541:    *
 542:    * @return TODO
 543:    */
 544:   public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x)
 545:   {
 546:     if (swingComponent != null)
 547:       swingComponent.getJComponent().requestFocus();
 548:     return swingComponent != null;
 549:   }
 550: 
 551:   /**
 552:    * Notifies the peer that the bounds of this component have changed. This
 553:    * is called by {@link Component#reshape(int, int, int, int)}.
 554:    *
 555:    * This is implemented to call setBounds() on the Swing component.
 556:    *
 557:    * @param x the X coordinate of the upper left corner of the component
 558:    * @param y the Y coordinate of the upper left corner of the component
 559:    * @param width the width of the component
 560:    * @param height the height of the component
 561:    */
 562:   public void reshape(int x, int y, int width, int height)
 563:   {
 564:     if (swingComponent != null)
 565:       swingComponent.getJComponent().setBounds(x, y, width, height);
 566:   }
 567: 
 568:   /**
 569:    * Sets the background color of the component. This is called by
 570:    * {@link Component#setBackground(Color)}.
 571:    *
 572:    * This is implemented to call setBackground() on the Swing component.
 573:    *
 574:    * @param color the background color to set
 575:    */
 576:   public void setBackground(Color color)
 577:   {
 578:     if (swingComponent != null)
 579:       swingComponent.getJComponent().setBackground(color);
 580:   }
 581: 
 582:   /**
 583:    * Notifies the peer that the bounds of this component have changed. This
 584:    * is called by {@link Component#setBounds(int, int, int, int)}.
 585:    *
 586:    * This is implemented to call setBounds() on the Swing component.
 587:    *
 588:    * @param x the X coordinate of the upper left corner of the component
 589:    * @param y the Y coordinate of the upper left corner of the component
 590:    * @param width the width of the component
 591:    * @param height the height of the component
 592:    */
 593:   public void setBounds(int x, int y, int width, int height)
 594:   {
 595:     reshape(x, y, width, height);
 596:   }
 597: 
 598:   /**
 599:    * Sets the cursor of the component. This is called by
 600:    * {@link Component#setCursor(Cursor)}.
 601:    *
 602:    * This is implemented to call setCursor() on the Swing component.
 603:    *
 604:    * @specnote Part of the earlier 1.1 API, apparently no longer needed.
 605:    */
 606:   public void setCursor(Cursor cursor)
 607:   {
 608:     if (swingComponent != null)
 609:       swingComponent.getJComponent().setCursor(cursor);
 610:   }
 611: 
 612:   /**
 613:    * Sets the enabled/disabled state of this component. This is called by
 614:    * {@link Component#setEnabled(boolean)}.
 615:    *
 616:    * This is implemented to call setEnabled() on the Swing component.
 617:    *
 618:    * @param enabled <code>true</code> to enable the component,
 619:    *        <code>false</code> to disable it
 620:    */
 621:   public void setEnabled(boolean enabled)
 622:   {
 623:     if (swingComponent != null)
 624:       swingComponent.getJComponent().setEnabled(enabled);
 625:   }
 626: 
 627:   /**
 628:    * Sets the font of the component. This is called by
 629:    * {@link Component#setFont(Font)}.
 630:    *
 631:    * This is implemented to call setFont() on the Swing component.
 632:    *
 633:    * @param font the font to set
 634:    */
 635:   public void setFont(Font font)
 636:   {
 637:     if (swingComponent != null)
 638:       swingComponent.getJComponent().setFont(font);
 639:   }
 640: 
 641:   /**
 642:    * Sets the foreground color of the component. This is called by
 643:    * {@link Component#setForeground(Color)}.
 644:    *
 645:    * This is implemented to call setForeground() on the Swing component.
 646:    *
 647:    * @param color the foreground color to set
 648:    */
 649:   public void setForeground(Color color)
 650:   {
 651:     if (swingComponent != null)
 652:       swingComponent.getJComponent().setForeground(color);
 653:   }
 654: 
 655:   /**
 656:    * Sets the visibility state of the component. This is called by
 657:    * {@link Component#setVisible(boolean)}.
 658:    *
 659:    * This is implemented to call setVisible() on the Swing component.
 660:    *
 661:    * @param visible <code>true</code> to make the component visible,
 662:    *        <code>false</code> to make it invisible
 663:    */
 664:   public void setVisible(boolean visible)
 665:   {
 666:     if (visible)
 667:       show();
 668:     else
 669:       hide();
 670:   }
 671: 
 672:   /**
 673:    * Makes the component visible. This is called by {@link Component#show()}.
 674:    *
 675:    * This is implemented to call setVisible(true) on the Swing component.
 676:    */
 677:   public void show()
 678:   {
 679:     if (swingComponent != null)
 680:       swingComponent.getJComponent().setVisible(true);
 681:   }
 682: 
 683:   /** 
 684:    * Get the graphics configuration of the component. The color model
 685:    * of the component can be derived from the configuration.
 686:    *
 687:    * This is implemented to return the GraphicsConfiguration of the parent
 688:    * component. This will eventually call the toplevel component peer, which
 689:    * is expected to provide a real implementation.
 690:    *
 691:    * @return the graphics configuration of the component
 692:    */
 693:   public GraphicsConfiguration getGraphicsConfiguration()
 694:   {
 695:     Component parent = awtComponent.getParent();
 696:     ComponentPeer parentPeer = parent.getPeer();
 697:     return parentPeer.getGraphicsConfiguration();
 698:   }
 699: 
 700:   /**
 701:    * Part of an older API, no longer needed.
 702:    */
 703:   public void setEventMask(long mask)
 704:   {
 705:     // Nothing to do here.
 706:   }
 707: 
 708:   /**
 709:    * Returns <code>true</code> if this component has been obscured,
 710:    * <code>false</code> otherwise. This will only work if
 711:    * {@link #canDetermineObscurity()} also returns <code>true</code>.
 712:    *
 713:    * This is not yet implemented.
 714:    *
 715:    * @return <code>true</code> if this component has been obscured,
 716:    *         <code>false</code> otherwise.
 717:    */
 718:   public boolean isObscured()
 719:   {
 720:     return false;
 721:   }
 722: 
 723:   /**
 724:    * Returns <code>true</code> if this component peer can determine if the
 725:    * component has been obscured, <code>false</code> otherwise.
 726:    *
 727:    * This is not yet implemented.
 728:    *
 729:    * @return <code>true</code> if this component peer can determine if the
 730:    *         component has been obscured, <code>false</code> otherwise
 731:    */
 732:   public boolean canDetermineObscurity()
 733:   {
 734:     return false;
 735:   }
 736: 
 737:   /**
 738:    * Coalesces the specified paint event.
 739:    *
 740:    * @param e the paint event
 741:    */
 742:   public void coalescePaintEvent(PaintEvent e)
 743:   {
 744:     // Nothing to do here yet.
 745:   }
 746: 
 747:   /**
 748:    * Updates the cursor. This is not yet implemented.
 749:    */
 750:   public void updateCursorImmediately()
 751:   {
 752:     // Nothing to do here yet.
 753:   }
 754: 
 755:   /**
 756:    * Returns true, if this component can handle wheel scrolling,
 757:    * <code>false</code> otherwise.
 758:    *
 759:    * This is not yet implemented and returns <code>false</code>. 
 760:    *
 761:    * @return true, if this component can handle wheel scrolling,
 762:    *         <code>false</code> otherwise
 763:    */
 764:   public boolean handlesWheelScrolling()
 765:   {
 766:     return false;
 767:   }
 768: 
 769:   /**
 770:    * A convenience method that creates a volatile image.  The volatile
 771:    * image is created on the screen device on which this component is
 772:    * displayed, in the device's current graphics configuration.
 773:    *
 774:    * This is implemented to let the parent component peer create an image.
 775:    * This eventually ends up in the toplevel component peer, which is then
 776:    * responsible for creating the real image.
 777:    *
 778:    * @param width width of the image
 779:    * @param height height of the image
 780:    *
 781:    * @see VolatileImage
 782:    *
 783:    * @since 1.2
 784:    */
 785:   public VolatileImage createVolatileImage(int width, int height)
 786:   {
 787:     Component parent = awtComponent.getParent();
 788:     VolatileImage im = null;
 789:     if (parent != null)
 790:       {
 791:         ComponentPeer parentPeer = parent.getPeer();
 792:         im = parentPeer.createVolatileImage(width, height);
 793:       }
 794:     return im;
 795:   }
 796: 
 797:   /**
 798:    * Create a number of image buffers that implement a buffering
 799:    * strategy according to the given capabilities.
 800:    *
 801:    * This is implemented to forward to the parent component peer. Eventually
 802:    * this ends up in the top level component peer, which is then responsible
 803:    * for doing the real work.
 804:    *
 805:    * @param numBuffers the number of buffers
 806:    * @param caps the buffering capabilities
 807:    *
 808:    * @throws AWTException if the specified buffering strategy is not
 809:    * implemented
 810:    *
 811:    * @since 1.2
 812:    */
 813:   public void createBuffers(int numBuffers, BufferCapabilities caps) throws AWTException
 814:   {
 815:     Component parent = awtComponent.getParent();
 816:     ComponentPeer parentPeer = parent.getPeer();
 817:     parentPeer.createBuffers(numBuffers, caps);
 818:   }
 819: 
 820:   /**
 821:    * Return the back buffer of this component.
 822:    *
 823:    * This is implemented to forward to the parent. Eventually this ends
 824:    * up in the toplevel component, which is then responsible for providing
 825:    * a back buffer.
 826:    *
 827:    * @return the back buffer of this component.
 828:    *
 829:    * @since 1.2
 830:    */
 831:   public Image getBackBuffer()
 832:   {
 833:     Component parent = awtComponent.getParent();
 834:     ComponentPeer parentPeer = parent.getPeer();
 835:     return parentPeer.getBackBuffer();
 836:   }
 837: 
 838:   /**
 839:    * Perform a page flip, leaving the contents of the back buffer in
 840:    * the specified state.
 841:    *
 842:    * This is implemented to forward to the parent. Eventually this ends
 843:    * up in the toplevel component, which is then responsible for doing the real
 844:    * work.
 845:    *
 846:    * @param contents the state in which to leave the back buffer
 847:    *
 848:    * @since 1.2
 849:    */
 850:   public void flip(FlipContents contents)
 851:   {
 852:     Component parent = awtComponent.getParent();
 853:     ComponentPeer parentPeer = parent.getPeer();
 854:     parentPeer.flip(contents);
 855:   }
 856: 
 857:   /**
 858:    * Destroy the resources created by createBuffers.
 859:    *
 860:    * This is implemented to forward to the parent component peer. Eventually
 861:    * this ends up in the top level component peer, which is then responsible
 862:    * for doing the real work.
 863:    *
 864:    * @since 1.2
 865:    */
 866:   public void destroyBuffers()
 867:   {
 868:     Component parent = awtComponent.getParent();
 869:     ComponentPeer parentPeer = parent.getPeer();
 870:     parentPeer.destroyBuffers();
 871:   }
 872: 
 873:   /**
 874:    * Get the bounds of this component peer.
 875:    *
 876:    * This is implemented to forward to the Swing component.
 877:    *
 878:    * @return component peer bounds
 879:    * @since 1.5
 880:    */
 881:   public Rectangle getBounds()
 882:   {
 883:     Rectangle retVal;
 884:     if (swingComponent != null)
 885:       retVal = swingComponent.getJComponent().getBounds();
 886:     else
 887:       retVal = new Rectangle();
 888:     return retVal;
 889:   }
 890: 
 891:   /**
 892:    * Reparent this component under another container.
 893:    * 
 894:    * @param parent
 895:    * @since 1.5
 896:    */
 897:   public void reparent(ContainerPeer parent)
 898:   {
 899:     // Nothing to do here.
 900:   }
 901: 
 902:   /**
 903:    * Set the bounds of this component peer.
 904:    *
 905:    * This is implemented to forward to the swing component.
 906:    *
 907:    * @param x the new x co-ordinate
 908:    * @param y the new y co-ordinate
 909:    * @param width the new width
 910:    * @param height the new height
 911:    * @param z the new stacking level
 912:    * @since 1.5
 913:    */
 914:   public void setBounds(int x, int y, int width, int height, int z)
 915:   {
 916:     if (swingComponent != null)
 917:       swingComponent.getJComponent().setBounds(x, y, width, height);
 918:     // FIXME: Somehow handle the Z order.
 919:   }
 920: 
 921:   /**
 922:    * Check if this component supports being reparented.
 923:    * 
 924:    * @return true if this component can be reparented,
 925:    * false otherwise.
 926:    * @since 1.5
 927:    */
 928:   public boolean isReparentSupported()
 929:   {
 930:     return true;
 931:   }
 932: 
 933: 
 934:   /**
 935:    * Layout this component peer.
 936:    *
 937:    * @since 1.5
 938:    */
 939:   public void layout()
 940:   {
 941:     if (swingComponent != null)
 942:       swingComponent.getJComponent().doLayout();
 943:   }
 944: 
 945:   /**
 946:    * Triggers 'heavyweight' painting of the components. This usually calls
 947:    * paint() on the Swing component.
 948:    *
 949:    * @param g the graphics context to use for painting
 950:    */
 951:   protected void peerPaint(Graphics g)
 952:   {
 953:     if (swingComponent != null)
 954:       swingComponent.getJComponent().paint(g);
 955:   }
 956: 
 957:   /**
 958:    * Handles mouse events on the component. This is usually forwarded to the
 959:    * SwingComponent's processMouseEvent() method.
 960:    *
 961:    * @param e the mouse event
 962:    */
 963:   protected void handleMouseEvent(MouseEvent e)
 964:   {
 965:     if (swingComponent != null)
 966:       swingComponent.handleMouseEvent(e);
 967:   }
 968: 
 969:   /**
 970:    * Handles mouse motion events on the component. This is usually forwarded
 971:    * to the SwingComponent's processMouseMotionEvent() method.
 972:    *
 973:    * @param e the mouse motion event
 974:    */
 975:   protected void handleMouseMotionEvent(MouseEvent e)
 976:   {
 977:     if (swingComponent != null)
 978:       swingComponent.handleMouseMotionEvent(e);
 979:   }
 980: 
 981:   /**
 982:    * Handles key events on the component. This is usually forwarded to the
 983:    * SwingComponent's processKeyEvent() method.
 984:    *
 985:    * @param e the key event
 986:    */
 987:   protected void handleKeyEvent(KeyEvent e)
 988:   {
 989:     if (swingComponent != null)
 990:       swingComponent.handleKeyEvent(e);
 991:   }
 992: 
 993:   /**
 994:    * Returns the AWT component for this peer.
 995:    *
 996:    * @return the AWT component for this peer
 997:    */
 998:   public Component getComponent()
 999:   {
1000:     return awtComponent;
1001:   }
1002: }