Source for java.awt.Canvas

   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: }