Frames | No Frames |
1: /* Canvas.java -- 2: Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation 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: 39: package java.awt; 40: 41: import java.awt.image.BufferStrategy; 42: import java.awt.peer.ComponentPeer; 43: import java.io.Serializable; 44: 45: import javax.accessibility.Accessible; 46: import javax.accessibility.AccessibleContext; 47: import javax.accessibility.AccessibleRole; 48: 49: /** 50: * The <code>Canvas</code> component provides a blank rectangular 51: * area, which the client application can use for drawing and for 52: * capturing events. By overriding the <code>paint()</code> method, 53: * the canvas can be used for anything from simple line drawings to 54: * full-scale custom components. 55: * 56: * @author Original author unknown 57: * @author Tom Tromey (tromey@redhat.com) 58: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 59: * @since 1.0 60: */ 61: 62: public class Canvas 63: extends Component 64: implements Serializable, Accessible 65: { 66: 67: /** 68: * Compatible with Sun's JDK. 69: */ 70: private static final long serialVersionUID = -2284879212465893870L; 71: 72: /** 73: * The number used to generate the name returned by getName. 74: */ 75: private static transient long next_canvas_number; 76: 77: /** 78: * The graphics configuration associated with the canvas. 79: */ 80: transient GraphicsConfiguration graphicsConfiguration; 81: 82: /** 83: * The buffer strategy associated with this canvas. 84: */ 85: transient BufferStrategy bufferStrategy; 86: 87: /** 88: * Initializes a new instance of <code>Canvas</code>. 89: */ 90: public Canvas() 91: { 92: } 93: 94: /** 95: * Initializes a new instance of <code>Canvas</code> 96: * with the supplied graphics configuration. 97: * 98: * @param graphicsConfiguration the graphics configuration to use 99: * for this particular canvas. 100: */ 101: public Canvas(GraphicsConfiguration graphicsConfiguration) 102: { 103: this.graphicsConfiguration = graphicsConfiguration; 104: } 105: 106: GraphicsConfiguration getGraphicsConfigurationImpl() 107: { 108: if (graphicsConfiguration != null) 109: return graphicsConfiguration; 110: return super.getGraphicsConfigurationImpl(); 111: } 112: 113: /** 114: * Creates the native peer for this object. 115: */ 116: public void addNotify() 117: { 118: if (peer == null) 119: peer = (ComponentPeer) getToolkit().createCanvas(this); 120: super.addNotify(); 121: } 122: 123: /** 124: * Repaints the canvas window. This method should be overridden by 125: * a subclass to do something useful, as this method simply paints 126: * the window with the background color. 127: * 128: * @param gfx the <code>Graphics</code> to use for painting 129: */ 130: public void paint(Graphics gfx) 131: { 132: /* This implementation doesn't make much sense since the filling 133: of background color is guaranteed for heavyweight components 134: such as this. But there's no need to worry, since paint() is 135: usually overridden anyway. */ 136: gfx.setColor(getBackground()); 137: Dimension size = getSize(); 138: gfx.fillRect(0, 0, size.width, size.height); 139: } 140: 141: /** 142: * This class provides accessibility support for the canvas. 143: */ 144: protected class AccessibleAWTCanvas 145: extends AccessibleAWTComponent 146: { 147: /** 148: * For compatability with Sun's JDK 149: */ 150: private static final long serialVersionUID = -6325592262103146699L; 151: 152: /** 153: * Constructor for the accessible canvas. 154: */ 155: protected AccessibleAWTCanvas() 156: { 157: } 158: 159: /** 160: * Returns the accessible role for the canvas. 161: * 162: * @return an instance of <code>AccessibleRole</code>, describing 163: * the role of the canvas. 164: */ 165: public AccessibleRole getAccessibleRole() 166: { 167: return AccessibleRole.CANVAS; 168: } 169: 170: } 171: 172: /** 173: * Gets the AccessibleContext associated with this <code>Canvas</code>. 174: * The context is created, if necessary. 175: * 176: * @return the associated context 177: */ 178: public AccessibleContext getAccessibleContext() 179: { 180: /* Create the context if this is the first request */ 181: if (accessibleContext == null) 182: accessibleContext = new AccessibleAWTCanvas(); 183: return accessibleContext; 184: } 185: 186: /** 187: * A BltBufferStrategy for canvases. 188: */ 189: private class CanvasBltBufferStrategy extends BltBufferStrategy 190: { 191: /** 192: * Creates a block transfer strategy for this canvas. 193: * 194: * @param numBuffers the number of buffers in this strategy 195: * @param accelerated true if the buffer should be accelerated, 196: * false otherwise 197: */ 198: CanvasBltBufferStrategy(int numBuffers, boolean accelerated) 199: { 200: super(numBuffers, 201: new BufferCapabilities(new ImageCapabilities(accelerated), 202: new ImageCapabilities(accelerated), 203: BufferCapabilities.FlipContents.COPIED)); 204: } 205: } 206: 207: /** 208: * A FlipBufferStrategy for canvases. 209: */ 210: private class CanvasFlipBufferStrategy extends FlipBufferStrategy 211: { 212: /** 213: * Creates a flip buffer strategy for this canvas. 214: * 215: * @param numBuffers the number of buffers in this strategy 216: * 217: * @throws AWTException if the requested number of buffers is not 218: * supported 219: */ 220: CanvasFlipBufferStrategy(int numBuffers) 221: throws AWTException 222: { 223: super(numBuffers, 224: new BufferCapabilities(new ImageCapabilities(true), 225: new ImageCapabilities(true), 226: BufferCapabilities.FlipContents.COPIED)); 227: } 228: } 229: 230: /** 231: * Creates a buffering strategy that manages how this canvas is 232: * repainted. This method attempts to create the optimum strategy 233: * based on the desired number of buffers. Hardware or software 234: * acceleration may be used. 235: * 236: * createBufferStrategy attempts different levels of optimization, 237: * but guarantees that some strategy with the requested number of 238: * buffers will be created even if it is not optimal. First it 239: * attempts to create a page flipping strategy, then an accelerated 240: * blitting strategy, then an unaccelerated blitting strategy. 241: * 242: * Calling this method causes any existing buffer strategy to be 243: * destroyed. 244: * 245: * @param numBuffers the number of buffers in this strategy 246: * 247: * @throws IllegalArgumentException if requested number of buffers 248: * is less than one 249: * @throws IllegalStateException if this canvas is not displayable 250: * 251: * @since 1.4 252: */ 253: public void createBufferStrategy(int numBuffers) 254: { 255: if (numBuffers < 1) 256: throw new IllegalArgumentException("Canvas.createBufferStrategy: number" 257: + " of buffers is less than one"); 258: 259: if (!isDisplayable()) 260: throw new IllegalStateException("Canvas.createBufferStrategy: canvas is" 261: + " not displayable"); 262: 263: BufferStrategy newStrategy = null; 264: 265: // try a flipping strategy 266: try 267: { 268: newStrategy = new CanvasFlipBufferStrategy(numBuffers); 269: } 270: catch (AWTException e) 271: { 272: } 273: 274: // fall back to an accelerated blitting strategy 275: if (newStrategy == null) 276: newStrategy = new CanvasBltBufferStrategy(numBuffers, true); 277: 278: bufferStrategy = newStrategy; 279: } 280: 281: /** 282: * Creates a buffering strategy that manages how this canvas is 283: * repainted. This method attempts to create a strategy based on 284: * the specified capabilities and throws an exception if the 285: * requested strategy is not supported. 286: * 287: * Calling this method causes any existing buffer strategy to be 288: * destroyed. 289: * 290: * @param numBuffers the number of buffers in this strategy 291: * @param caps the requested buffering capabilities 292: * 293: * @throws AWTException if the requested capabilities are not 294: * supported 295: * @throws IllegalArgumentException if requested number of buffers 296: * is less than one or if caps is null 297: * 298: * @since 1.4 299: */ 300: public void createBufferStrategy(int numBuffers, BufferCapabilities caps) 301: throws AWTException 302: { 303: if (numBuffers < 1) 304: throw new IllegalArgumentException("Canvas.createBufferStrategy: number" 305: + " of buffers is less than one"); 306: 307: if (caps == null) 308: throw new IllegalArgumentException("Canvas.createBufferStrategy:" 309: + " capabilities object is null"); 310: 311: // a flipping strategy was requested 312: if (caps.isPageFlipping()) 313: bufferStrategy = new CanvasFlipBufferStrategy(numBuffers); 314: else 315: bufferStrategy = new CanvasBltBufferStrategy(numBuffers, true); 316: } 317: 318: /** 319: * Returns the buffer strategy used by the canvas. 320: * 321: * @return the buffer strategy. 322: * @since 1.4 323: */ 324: public BufferStrategy getBufferStrategy() 325: { 326: return bufferStrategy; 327: } 328: 329: /** 330: * Updates the canvas in response to a request to 331: * <code>repaint()</code> it. The canvas is cleared 332: * with the current background colour, before <code>paint()</code> 333: * is called to add the new contents. Subclasses 334: * which override this method should either call this 335: * method via <code>super.update(graphics)</code> or re-implement 336: * this behaviour, so as to ensure that the canvas is 337: * clear before painting takes place. 338: * 339: * @param graphics the graphics context. 340: */ 341: public void update(Graphics graphics) 342: { 343: Dimension size; 344: 345: /* Clear the canvas */ 346: size = getSize(); 347: graphics.clearRect(0, 0, size.width, size.height); 348: /* Call the paint method */ 349: paint(graphics); 350: } 351: 352: /** 353: * Generate a unique name for this <code>Canvas</code>. 354: * 355: * @return A unique name for this <code>Canvas</code>. 356: */ 357: String generateName() 358: { 359: return "canvas" + getUniqueLong(); 360: } 361: 362: private static synchronized long getUniqueLong() 363: { 364: return next_canvas_number++; 365: } 366: }