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