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 */ Canvas()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 */ Canvas(GraphicsConfiguration graphicsConfiguration)96 public Canvas(GraphicsConfiguration graphicsConfiguration) 97 { 98 this.graphicsConfig = graphicsConfiguration; 99 } 100 101 /** 102 * Creates the native peer for this object. 103 */ addNotify()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 */ paint(Graphics gfx)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 */ AccessibleAWTCanvas()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 */ getAccessibleRole()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 */ getAccessibleContext()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 */ CanvasBltBufferStrategy(int numBuffers, boolean accelerated)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 */ CanvasFlipBufferStrategy(int numBuffers)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 */ createBufferStrategy(int numBuffers)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 */ createBufferStrategy(int numBuffers, BufferCapabilities caps)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 */ getBufferStrategy()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 */ update(Graphics graphics)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 */ generateName()345 String generateName() 346 { 347 return "canvas" + getUniqueLong(); 348 } 349 getUniqueLong()350 private static synchronized long getUniqueLong() 351 { 352 return next_canvas_number++; 353 } 354 } 355