1 /* SwingContainerPeer.java -- A Swing based peer for AWT containers
2 Copyright (C) 2006, 2007 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 protected 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 protected synchronized void removeHeavyweightDescendent(Component comp)
111 heavyweightDescendents.remove(comp);
116 * Returns an array of all registered heavyweight descendents.
118 * @return all registered heavyweight descendents
120 protected Component[] getHeavyweightDescendents()
122 Component[] heavyweights = new Component[heavyweightDescendents.size()];
123 heavyweights = (Component[]) heavyweightDescendents.toArray(heavyweights);
128 * Returns the insets of the container.
130 * This is implemented to return the insets of the Swing container.
132 * @return the insets of the container
134 public Insets insets()
137 if (swingComponent != null)
138 retVal = swingComponent.getJComponent().getInsets();
140 retVal = new Insets(0, 0, 0, 0);
145 * Returns the insets of the container.
147 * This is implemented to return the insets of the Swing container.
149 * @return the insets of the container
151 public Insets getInsets()
157 * Called before the validation of this containers begins.
159 public void beginValidate()
161 // Nothing to do here.
165 * Called after the validation of this containers ended.
167 public void endValidate()
169 // Nothing to do here.
173 * Called before the layout of this containers begins.
175 public void beginLayout()
177 // Nothing to do here.
181 * Called after the layout of this containers ended.
183 public void endLayout()
185 // Nothing to do here.
189 * Returns <code>false</code> unconditionally. This method is not used at
192 * @return <code>false</code>
194 public boolean isPaintPending()
200 * Returns <code>false</code> unconditionally. This method is not used at
203 * @return <code>false</code>
205 public boolean isRestackSupported()
211 * This method is not used at the moment.
213 public void cancelPendingPaint(int x, int y, int width, int height)
215 // Nothing to do here.
219 * This method is not used at the moment.
221 public void restack()
223 // Nothing to do here.
227 * Performs the super behaviour (call peerPaintComponent() and
228 * awtComponent.paint()), and forwards the paint request to the heavyweight
229 * descendents of the container.
231 protected void peerPaint(Graphics g, boolean update)
233 if (isDoubleBuffering())
235 int width = awtComponent.getWidth();
236 int height = awtComponent.getHeight();
237 if (backbuffer == null
238 || backbuffer.getWidth(awtComponent) < width
239 || backbuffer.getHeight(awtComponent) < height)
240 backbuffer = awtComponent.createImage(width, height);
241 Graphics g2 = backbuffer.getGraphics();
242 Rectangle clip = g.getClipRect();
246 super.peerPaint(g2, update);
247 peerPaintChildren(g2);
253 g.drawImage(backbuffer, 0, 0, awtComponent);
257 super.peerPaint(g, update);
258 peerPaintChildren(g);
263 * Determines if we should do double buffering or not.
265 * @return if we should do double buffering or not
267 private boolean isDoubleBuffering()
270 SystemProperties.getProperty("gnu.awt.swing.doublebuffering", "false");
271 return prop.equals("true");
275 * Paints any heavyweight child components.
277 * @param g the graphics to use for painting
279 protected synchronized void peerPaintChildren(Graphics g)
281 // TODO: Is this the right painting order?
282 for (Iterator i = heavyweightDescendents.iterator(); i.hasNext();)
284 Component child = (Component) i.next();
285 ComponentPeer peer = child.getPeer();
287 if (peer instanceof SwingComponentPeer && child.isVisible())
289 // TODO: The translation here doesn't work for deeper
290 // nested children. Fix this!
291 Graphics g2 = g.create(child.getX(), child.getY(),
292 child.getWidth(), child.getHeight());
295 // update() is only called for the topmost component if
296 // necessary, all other components only get paint() called.
297 ((SwingComponentPeer) peer).peerPaint(g2, false);
308 * Handles mouse events by dispatching it to the correct component.
310 * @param ev the mouse event
312 protected void handleMouseEvent(MouseEvent ev)
314 Component comp = awtComponent.getComponentAt(ev.getPoint());
315 if(comp == null) comp = awtComponent;
316 ComponentPeer peer = comp.getPeer();
317 if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
319 ev.translatePoint(comp.getX(), comp.getY());
321 ((SwingComponentPeer) peer).handleMouseEvent(ev);
326 * Handles mouse events by dispatching it to the correct component.
328 * @param ev the mouse event
330 protected void handleMouseMotionEvent(MouseEvent ev)
332 Component comp = awtComponent.getComponentAt(ev.getPoint());
335 ComponentPeer peer = comp.getPeer();
336 if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
338 ev.translatePoint(comp.getX(), comp.getY());
339 ((SwingComponentPeer) peer).handleMouseMotionEvent(ev);
345 * Handles key events on the component. This is usually forwarded to the
346 * SwingComponent's processKeyEvent() method.
348 * @param e the key event
350 protected void handleKeyEvent(KeyEvent e)
352 Component owner = getFocusOwner();
354 owner.getPeer().handleEvent(e);
356 super.handleKeyEvent(e);
359 private Component focusOwner = null;
361 private Component getFocusOwner()
363 if(focusOwner == null)
365 for(Iterator iter=heavyweightDescendents.iterator(); iter.hasNext();)
367 Component child = (Component) iter.next();
368 if(child.isFocusable())