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