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

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