| /* Canvas.java -- | |
| Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package java.awt; | |
| import java.awt.image.BufferStrategy; | |
| import java.awt.peer.ComponentPeer; | |
| import java.io.Serializable; | |
| import javax.accessibility.Accessible; | |
| import javax.accessibility.AccessibleContext; | |
| import javax.accessibility.AccessibleRole; | |
| /** | |
| * The <code>Canvas</code> component provides a blank rectangular | |
| * area, which the client application can use for drawing and for | |
| * capturing events. By overriding the <code>paint()</code> method, | |
| * the canvas can be used for anything from simple line drawings to | |
| * full-scale custom components. | |
| * | |
| * @author Original author unknown | |
| * @author Tom Tromey (tromey@redhat.com) | |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) | |
| * @since 1.0 | |
| */ | |
| public class Canvas | |
| extends Component | |
| implements Serializable, Accessible | |
| { | |
| /** | |
| * Compatible with Sun's JDK. | |
| */ | |
| private static final long serialVersionUID = -2284879212465893870L; | |
| /** | |
| * The number used to generate the name returned by getName. | |
| */ | |
| private static transient long next_canvas_number; | |
| /** | |
| * The graphics configuration associated with the canvas. | |
| */ | |
| transient GraphicsConfiguration graphicsConfiguration; | |
| /** | |
| * The buffer strategy associated with this canvas. | |
| */ | |
| transient BufferStrategy bufferStrategy; | |
| /** | |
| * Initializes a new instance of <code>Canvas</code>. | |
| */ | |
| public Canvas() | |
| { | |
| } | |
| /** | |
| * Initializes a new instance of <code>Canvas</code> | |
| * with the supplied graphics configuration. | |
| * | |
| * @param graphicsConfiguration the graphics configuration to use | |
| * for this particular canvas. | |
| */ | |
| public Canvas(GraphicsConfiguration graphicsConfiguration) | |
| { | |
| this.graphicsConfiguration = graphicsConfiguration; | |
| } | |
| GraphicsConfiguration getGraphicsConfigurationImpl() | |
| { | |
| if (graphicsConfiguration != null) | |
| return graphicsConfiguration; | |
| return super.getGraphicsConfigurationImpl(); | |
| } | |
| /** | |
| * Creates the native peer for this object. | |
| */ | |
| public void addNotify() | |
| { | |
| if (peer == null) | |
| peer = (ComponentPeer) getToolkit().createCanvas(this); | |
| super.addNotify(); | |
| } | |
| /** | |
| * Repaints the canvas window. This method should be overridden by | |
| * a subclass to do something useful, as this method simply paints | |
| * the window with the background color. | |
| * | |
| * @param gfx the <code>Graphics</code> to use for painting | |
| */ | |
| public void paint(Graphics gfx) | |
| { | |
| /* This implementation doesn't make much sense since the filling | |
| of background color is guaranteed for heavyweight components | |
| such as this. But there's no need to worry, since paint() is | |
| usually overridden anyway. */ | |
| gfx.setColor(getBackground()); | |
| Dimension size = getSize(); | |
| gfx.fillRect(0, 0, size.width, size.height); | |
| } | |
| /** | |
| * This class provides accessibility support for the canvas. | |
| */ | |
| protected class AccessibleAWTCanvas | |
| extends AccessibleAWTComponent | |
| { | |
| /** | |
| * For compatability with Sun's JDK | |
| */ | |
| private static final long serialVersionUID = -6325592262103146699L; | |
| /** | |
| * Constructor for the accessible canvas. | |
| */ | |
| protected AccessibleAWTCanvas() | |
| { | |
| } | |
| /** | |
| * Returns the accessible role for the canvas. | |
| * | |
| * @return an instance of <code>AccessibleRole</code>, describing | |
| * the role of the canvas. | |
| */ | |
| public AccessibleRole getAccessibleRole() | |
| { | |
| return AccessibleRole.CANVAS; | |
| } | |
| } | |
| /** | |
| * Gets the AccessibleContext associated with this <code>Canvas</code>. | |
| * The context is created, if necessary. | |
| * | |
| * @return the associated context | |
| */ | |
| public AccessibleContext getAccessibleContext() | |
| { | |
| /* Create the context if this is the first request */ | |
| if (accessibleContext == null) | |
| accessibleContext = new AccessibleAWTCanvas(); | |
| return accessibleContext; | |
| } | |
| /** | |
| * A BltBufferStrategy for canvases. | |
| */ | |
| private class CanvasBltBufferStrategy extends BltBufferStrategy | |
| { | |
| /** | |
| * Creates a block transfer strategy for this canvas. | |
| * | |
| * @param numBuffers the number of buffers in this strategy | |
| * @param accelerated true if the buffer should be accelerated, | |
| * false otherwise | |
| */ | |
| CanvasBltBufferStrategy(int numBuffers, boolean accelerated) | |
| { | |
| super(numBuffers, | |
| new BufferCapabilities(new ImageCapabilities(accelerated), | |
| new ImageCapabilities(accelerated), | |
| BufferCapabilities.FlipContents.COPIED)); | |
| } | |
| } | |
| /** | |
| * A FlipBufferStrategy for canvases. | |
| */ | |
| private class CanvasFlipBufferStrategy extends FlipBufferStrategy | |
| { | |
| /** | |
| * Creates a flip buffer strategy for this canvas. | |
| * | |
| * @param numBuffers the number of buffers in this strategy | |
| * | |
| * @throws AWTException if the requested number of buffers is not | |
| * supported | |
| */ | |
| CanvasFlipBufferStrategy(int numBuffers) | |
| throws AWTException | |
| { | |
| super(numBuffers, | |
| new BufferCapabilities(new ImageCapabilities(true), | |
| new ImageCapabilities(true), | |
| BufferCapabilities.FlipContents.COPIED)); | |
| } | |
| } | |
| /** | |
| * Creates a buffering strategy that manages how this canvas is | |
| * repainted. This method attempts to create the optimum strategy | |
| * based on the desired number of buffers. Hardware or software | |
| * acceleration may be used. | |
| * | |
| * createBufferStrategy attempts different levels of optimization, | |
| * but guarantees that some strategy with the requested number of | |
| * buffers will be created even if it is not optimal. First it | |
| * attempts to create a page flipping strategy, then an accelerated | |
| * blitting strategy, then an unaccelerated blitting strategy. | |
| * | |
| * Calling this method causes any existing buffer strategy to be | |
| * destroyed. | |
| * | |
| * @param numBuffers the number of buffers in this strategy | |
| * | |
| * @throws IllegalArgumentException if requested number of buffers | |
| * is less than one | |
| * @throws IllegalStateException if this canvas is not displayable | |
| * | |
| * @since 1.4 | |
| */ | |
| public void createBufferStrategy(int numBuffers) | |
| { | |
| if (numBuffers < 1) | |
| throw new IllegalArgumentException("Canvas.createBufferStrategy: number" | |
| + " of buffers is less than one"); | |
| if (!isDisplayable()) | |
| throw new IllegalStateException("Canvas.createBufferStrategy: canvas is" | |
| + " not displayable"); | |
| BufferStrategy newStrategy = null; | |
| // try a flipping strategy | |
| try | |
| { | |
| newStrategy = new CanvasFlipBufferStrategy(numBuffers); | |
| } | |
| catch (AWTException e) | |
| { | |
| } | |
| // fall back to an accelerated blitting strategy | |
| if (newStrategy == null) | |
| newStrategy = new CanvasBltBufferStrategy(numBuffers, true); | |
| bufferStrategy = newStrategy; | |
| } | |
| /** | |
| * Creates a buffering strategy that manages how this canvas is | |
| * repainted. This method attempts to create a strategy based on | |
| * the specified capabilities and throws an exception if the | |
| * requested strategy is not supported. | |
| * | |
| * Calling this method causes any existing buffer strategy to be | |
| * destroyed. | |
| * | |
| * @param numBuffers the number of buffers in this strategy | |
| * @param caps the requested buffering capabilities | |
| * | |
| * @throws AWTException if the requested capabilities are not | |
| * supported | |
| * @throws IllegalArgumentException if requested number of buffers | |
| * is less than one or if caps is null | |
| * | |
| * @since 1.4 | |
| */ | |
| public void createBufferStrategy(int numBuffers, BufferCapabilities caps) | |
| throws AWTException | |
| { | |
| if (numBuffers < 1) | |
| throw new IllegalArgumentException("Canvas.createBufferStrategy: number" | |
| + " of buffers is less than one"); | |
| if (caps == null) | |
| throw new IllegalArgumentException("Canvas.createBufferStrategy:" | |
| + " capabilities object is null"); | |
| // a flipping strategy was requested | |
| if (caps.isPageFlipping()) | |
| bufferStrategy = new CanvasFlipBufferStrategy(numBuffers); | |
| else | |
| bufferStrategy = new CanvasBltBufferStrategy(numBuffers, true); | |
| } | |
| /** | |
| * Returns the buffer strategy used by the canvas. | |
| * | |
| * @return the buffer strategy. | |
| * @since 1.4 | |
| */ | |
| public BufferStrategy getBufferStrategy() | |
| { | |
| return bufferStrategy; | |
| } | |
| /** | |
| * Updates the canvas in response to a request to | |
| * <code>repaint()</code> it. The canvas is cleared | |
| * with the current background colour, before <code>paint()</code> | |
| * is called to add the new contents. Subclasses | |
| * which override this method should either call this | |
| * method via <code>super.update(graphics)</code> or re-implement | |
| * this behaviour, so as to ensure that the canvas is | |
| * clear before painting takes place. | |
| * | |
| * @param graphics the graphics context. | |
| */ | |
| public void update(Graphics graphics) | |
| { | |
| Dimension size; | |
| /* Clear the canvas */ | |
| size = getSize(); | |
| graphics.clearRect(0, 0, size.width, size.height); | |
| /* Call the paint method */ | |
| paint(graphics); | |
| } | |
| /** | |
| * Generate a unique name for this <code>Canvas</code>. | |
| * | |
| * @return A unique name for this <code>Canvas</code>. | |
| */ | |
| String generateName() | |
| { | |
| return "canvas" + getUniqueLong(); | |
| } | |
| private static synchronized long getUniqueLong() | |
| { | |
| return next_canvas_number++; | |
| } | |
| } |