1 /* SwingContainerPeer.java -- A Swing based peer for AWT containers
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
38 package gnu.java.awt.peer.swing;
40 import gnu.classpath.SystemProperties;
42 import java.awt.Component;
43 import java.awt.Container;
44 import java.awt.Graphics;
45 import java.awt.Image;
46 import java.awt.Insets;
47 import java.awt.Rectangle;
48 import java.awt.event.KeyEvent;
49 import java.awt.event.MouseEvent;
50 import java.awt.peer.ComponentPeer;
51 import java.awt.peer.ContainerPeer;
52 import java.util.Iterator;
53 import java.util.LinkedList;
56 * A peer for Container to be used with the Swing based AWT peers.
58 * @author Roman Kennke (kennke@aicas.com)
60 public class SwingContainerPeer
61 extends SwingComponentPeer
62 implements ContainerPeer
66 * Stores all heavyweight descendents of the container. This is used
67 * in {@link #peerPaintChildren(Graphics)}.
69 private LinkedList heavyweightDescendents;
72 * The backbuffer used for painting UPDATE events.
74 private Image backbuffer;
77 * Creates a new SwingContainerPeer.
81 public SwingContainerPeer(Container awtCont)
83 heavyweightDescendents = new LinkedList();
87 * Registers a heavyweight descendent. This is then painted by
88 * {@link #peerPaintChildren(Graphics)}.
90 * @param comp the descendent to register
92 * @see #peerPaintChildren(Graphics)
93 * @see #removeHeavyweightDescendent(Component)
95 synchronized void addHeavyweightDescendent(Component comp)
97 heavyweightDescendents.add(comp);
102 * Unregisters a heavyweight descendent.
104 * @param comp the descendent to unregister
106 * @see #peerPaintChildren(Graphics)
107 * @see #addHeavyweightDescendent(Component)
109 synchronized void removeHeavyweightDescendent(Component comp)
111 heavyweightDescendents.remove(comp);
116 * Returns the insets of the container.
118 * This is implemented to return the insets of the Swing container.
120 * @return the insets of the container
122 public Insets insets()
125 if (swingComponent != null)
126 retVal = swingComponent.getJComponent().getInsets();
128 retVal = new Insets(0, 0, 0, 0);
133 * Returns the insets of the container.
135 * This is implemented to return the insets of the Swing container.
137 * @return the insets of the container
139 public Insets getInsets()
145 * Called before the validation of this containers begins.
147 public void beginValidate()
149 // Nothing to do here.
153 * Called after the validation of this containers ended.
155 public void endValidate()
157 // Nothing to do here.
161 * Called before the layout of this containers begins.
163 public void beginLayout()
165 // Nothing to do here.
169 * Called after the layout of this containers ended.
171 public void endLayout()
173 // Nothing to do here.
177 * Returns <code>false</code> unconditionally. This method is not used at
180 * @return <code>false</code>
182 public boolean isPaintPending()
188 * Returns <code>false</code> unconditionally. This method is not used at
191 * @return <code>false</code>
193 public boolean isRestackSupported()
199 * This method is not used at the moment.
201 public void cancelPendingPaint(int x, int y, int width, int height)
203 // Nothing to do here.
207 * This method is not used at the moment.
209 public void restack()
211 // Nothing to do here.
215 * Performs the super behaviour (call peerPaintComponent() and
216 * awtComponent.paint()), and forwards the paint request to the heavyweight
217 * descendents of the container.
219 protected void peerPaint(Graphics g, boolean update)
221 if (isDoubleBuffering())
223 int width = awtComponent.getWidth();
224 int height = awtComponent.getHeight();
225 if (backbuffer == null
226 || backbuffer.getWidth(awtComponent) < width
227 || backbuffer.getHeight(awtComponent) < height)
228 backbuffer = awtComponent.createImage(width, height);
229 Graphics g2 = backbuffer.getGraphics();
230 Rectangle clip = g.getClipRect();
234 super.peerPaint(g2, update);
235 peerPaintChildren(g2);
241 g.drawImage(backbuffer, 0, 0, awtComponent);
245 super.peerPaint(g, update);
246 peerPaintChildren(g);
251 * Determines if we should do double buffering or not.
253 * @return if we should do double buffering or not
255 private boolean isDoubleBuffering()
258 SystemProperties.getProperty("gnu.awt.swing.doublebuffering", "false");
259 return prop.equals("true");
263 * Paints any heavyweight child components.
265 * @param g the graphics to use for painting
267 protected synchronized void peerPaintChildren(Graphics g)
269 // TODO: Is this the right painting order?
270 for (Iterator i = heavyweightDescendents.iterator(); i.hasNext();)
272 Component child = (Component) i.next();
273 ComponentPeer peer = child.getPeer();
275 if (peer instanceof SwingComponentPeer && child.isVisible())
277 // TODO: The translation here doesn't work for deeper
278 // nested children. Fix this!
279 Graphics g2 = g.create(child.getX(), child.getY(),
280 child.getWidth(), child.getHeight());
283 // update() is only called for the topmost component if
284 // necessary, all other components only get paint() called.
285 ((SwingComponentPeer) peer).peerPaint(g2, false);
296 * Handles mouse events by dispatching it to the correct component.
298 * @param ev the mouse event
300 protected void handleMouseEvent(MouseEvent ev)
302 Component comp = awtComponent.getComponentAt(ev.getPoint());
303 if(comp == null) comp = awtComponent;
304 ComponentPeer peer = comp.getPeer();
305 if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
307 ev.translatePoint(comp.getX(), comp.getY());
309 ((SwingComponentPeer) peer).handleMouseEvent(ev);
314 * Handles mouse events by dispatching it to the correct component.
316 * @param ev the mouse event
318 protected void handleMouseMotionEvent(MouseEvent ev)
320 Component comp = awtComponent.getComponentAt(ev.getPoint());
323 ComponentPeer peer = comp.getPeer();
324 if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
326 ev.translatePoint(comp.getX(), comp.getY());
327 ((SwingComponentPeer) peer).handleMouseMotionEvent(ev);
333 * Handles key events on the component. This is usually forwarded to the
334 * SwingComponent's processKeyEvent() method.
336 * @param e the key event
338 protected void handleKeyEvent(KeyEvent e)
340 Component owner = getFocusOwner();
342 owner.dispatchEvent(e);
344 super.handleKeyEvent(e);
347 private Component focusOwner = null;
349 private Component getFocusOwner()
351 if(focusOwner == null)
353 for(Iterator iter=heavyweightDescendents.iterator(); iter.hasNext();)
355 Component child = (Component) iter.next();
356 if(child.isFocusable())