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