OSDN Git Service

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