Frames | No Frames |
1: /* SwingContainerPeer.java -- A Swing based peer for AWT containers 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 gnu.classpath.SystemProperties; 41: 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; 54: 55: /** 56: * A peer for Container to be used with the Swing based AWT peers. 57: * 58: * @author Roman Kennke (kennke@aicas.com) 59: */ 60: public class SwingContainerPeer 61: extends SwingComponentPeer 62: implements ContainerPeer 63: { 64: 65: /** 66: * Stores all heavyweight descendents of the container. This is used 67: * in {@link #peerPaintChildren(Graphics)}. 68: */ 69: private LinkedList heavyweightDescendents; 70: 71: /** 72: * The backbuffer used for painting UPDATE events. 73: */ 74: private Image backbuffer; 75: 76: /** 77: * Creates a new SwingContainerPeer. 78: * 79: * @param awtCont 80: */ 81: public SwingContainerPeer(Container awtCont) 82: { 83: heavyweightDescendents = new LinkedList(); 84: } 85: 86: /** 87: * Registers a heavyweight descendent. This is then painted by 88: * {@link #peerPaintChildren(Graphics)}. 89: * 90: * @param comp the descendent to register 91: * 92: * @see #peerPaintChildren(Graphics) 93: * @see #removeHeavyweightDescendent(Component) 94: */ 95: protected synchronized void addHeavyweightDescendent(Component comp) 96: { 97: heavyweightDescendents.add(comp); 98: focusOwner = null; 99: } 100: 101: /** 102: * Unregisters a heavyweight descendent. 103: * 104: * @param comp the descendent to unregister 105: * 106: * @see #peerPaintChildren(Graphics) 107: * @see #addHeavyweightDescendent(Component) 108: */ 109: protected synchronized void removeHeavyweightDescendent(Component comp) 110: { 111: heavyweightDescendents.remove(comp); 112: focusOwner = null; 113: } 114: 115: /** 116: * Returns an array of all registered heavyweight descendents. 117: * 118: * @return all registered heavyweight descendents 119: */ 120: protected Component[] getHeavyweightDescendents() 121: { 122: Component[] heavyweights = new Component[heavyweightDescendents.size()]; 123: heavyweights = (Component[]) heavyweightDescendents.toArray(heavyweights); 124: return heavyweights; 125: } 126: 127: /** 128: * Returns the insets of the container. 129: * 130: * This is implemented to return the insets of the Swing container. 131: * 132: * @return the insets of the container 133: */ 134: public Insets insets() 135: { 136: Insets retVal; 137: if (swingComponent != null) 138: retVal = swingComponent.getJComponent().getInsets(); 139: else 140: retVal = new Insets(0, 0, 0, 0); 141: return retVal; 142: } 143: 144: /** 145: * Returns the insets of the container. 146: * 147: * This is implemented to return the insets of the Swing container. 148: * 149: * @return the insets of the container 150: */ 151: public Insets getInsets() 152: { 153: return insets(); 154: } 155: 156: /** 157: * Called before the validation of this containers begins. 158: */ 159: public void beginValidate() 160: { 161: // Nothing to do here. 162: } 163: 164: /** 165: * Called after the validation of this containers ended. 166: */ 167: public void endValidate() 168: { 169: // Nothing to do here. 170: } 171: 172: /** 173: * Called before the layout of this containers begins. 174: */ 175: public void beginLayout() 176: { 177: // Nothing to do here. 178: } 179: 180: /** 181: * Called after the layout of this containers ended. 182: */ 183: public void endLayout() 184: { 185: // Nothing to do here. 186: } 187: 188: /** 189: * Returns <code>false</code> unconditionally. This method is not used at 190: * the moment. 191: * 192: * @return <code>false</code> 193: */ 194: public boolean isPaintPending() 195: { 196: return false; 197: } 198: 199: /** 200: * Returns <code>false</code> unconditionally. This method is not used at 201: * the moment. 202: * 203: * @return <code>false</code> 204: */ 205: public boolean isRestackSupported() 206: { 207: return false; 208: } 209: 210: /** 211: * This method is not used at the moment. 212: */ 213: public void cancelPendingPaint(int x, int y, int width, int height) 214: { 215: // Nothing to do here. 216: } 217: 218: /** 219: * This method is not used at the moment. 220: */ 221: public void restack() 222: { 223: // Nothing to do here. 224: } 225: 226: /** 227: * Performs the super behaviour (call peerPaintComponent() and 228: * awtComponent.paint()), and forwards the paint request to the heavyweight 229: * descendents of the container. 230: */ 231: protected void peerPaint(Graphics g, boolean update) 232: { 233: if (isDoubleBuffering()) 234: { 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(); 243: try 244: { 245: g2.setClip(clip); 246: super.peerPaint(g2, update); 247: peerPaintChildren(g2); 248: } 249: finally 250: { 251: g2.dispose(); 252: } 253: g.drawImage(backbuffer, 0, 0, awtComponent); 254: } 255: else 256: { 257: super.peerPaint(g, update); 258: peerPaintChildren(g); 259: } 260: } 261: 262: /** 263: * Determines if we should do double buffering or not. 264: * 265: * @return if we should do double buffering or not 266: */ 267: private boolean isDoubleBuffering() 268: { 269: Object prop = 270: SystemProperties.getProperty("gnu.awt.swing.doublebuffering", "false"); 271: return prop.equals("true"); 272: } 273: 274: /** 275: * Paints any heavyweight child components. 276: * 277: * @param g the graphics to use for painting 278: */ 279: protected synchronized void peerPaintChildren(Graphics g) 280: { 281: // TODO: Is this the right painting order? 282: for (Iterator i = heavyweightDescendents.iterator(); i.hasNext();) 283: { 284: Component child = (Component) i.next(); 285: ComponentPeer peer = child.getPeer(); 286: 287: if (peer instanceof SwingComponentPeer && child.isVisible()) 288: { 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()); 293: try 294: { 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); 298: } 299: finally 300: { 301: g2.dispose(); 302: } 303: } 304: } 305: } 306: 307: /** 308: * Handles mouse events by dispatching it to the correct component. 309: * 310: * @param ev the mouse event 311: */ 312: protected void handleMouseEvent(MouseEvent ev) 313: { 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) 318: { 319: ev.translatePoint(comp.getX(), comp.getY()); 320: ev.setSource(comp); 321: ((SwingComponentPeer) peer).handleMouseEvent(ev); 322: } 323: } 324: 325: /** 326: * Handles mouse events by dispatching it to the correct component. 327: * 328: * @param ev the mouse event 329: */ 330: protected void handleMouseMotionEvent(MouseEvent ev) 331: { 332: Component comp = awtComponent.getComponentAt(ev.getPoint()); 333: if (comp != null) 334: { 335: ComponentPeer peer = comp.getPeer(); 336: if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer) 337: { 338: ev.translatePoint(comp.getX(), comp.getY()); 339: ((SwingComponentPeer) peer).handleMouseMotionEvent(ev); 340: } 341: } 342: } 343: 344: /** 345: * Handles key events on the component. This is usually forwarded to the 346: * SwingComponent's processKeyEvent() method. 347: * 348: * @param e the key event 349: */ 350: protected void handleKeyEvent(KeyEvent e) 351: { 352: Component owner = getFocusOwner(); 353: if(owner != null) 354: owner.getPeer().handleEvent(e); 355: else 356: super.handleKeyEvent(e); 357: } 358: 359: private Component focusOwner = null; 360: 361: private Component getFocusOwner() 362: { 363: if(focusOwner == null) 364: { 365: for(Iterator iter=heavyweightDescendents.iterator(); iter.hasNext();) 366: { 367: Component child = (Component) iter.next(); 368: if(child.isFocusable()) 369: { 370: focusOwner = child; 371: break; 372: } 373: } 374: } 375: return focusOwner; 376: } 377: 378: }