Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.canvas;
027
028import com.sun.javafx.geom.BaseBounds;
029import com.sun.javafx.geom.RectBounds;
030import com.sun.javafx.geom.transform.BaseTransform;
031import com.sun.javafx.jmx.MXNodeAlgorithm;
032import com.sun.javafx.jmx.MXNodeAlgorithmContext;
033import com.sun.javafx.scene.DirtyBits;
034import com.sun.javafx.sg.GrowableDataBuffer;
035import com.sun.javafx.sg.PGCanvas;
036import com.sun.javafx.sg.PGNode;
037import com.sun.javafx.tk.Toolkit;
038import javafx.beans.property.DoubleProperty;
039import javafx.beans.property.DoublePropertyBase;
040import javafx.geometry.NodeOrientation;
041import javafx.scene.Node;
042
043/**
044 * {@code Canvas} is an image that can be drawn on using a set of graphics 
045 * commands provided by a {@code GraphicsContext}. 
046 * 
047 * <p>
048 * A {@code Canvas} node is constructed with a width and height that specifies the size 
049 * of the image into which the canvas drawing commands are rendered. All drawing 
050 * operations are clipped to the bounds of that image.
051 * 
052 * <p>Example:</p>
053 *
054 * <p>
055 * <pre>
056import javafx.scene.*;
057import javafx.scene.paint.*;
058import javafx.scene.canvas.*;
059
060Group root = new Group();
061Scene s = new Scene(root, 300, 300, Color.BLACK);
062
063final Canvas canvas = new Canvas(250,250);
064GraphicsContext gc = canvas.getGraphicsContext2D();
065 
066gc.setFill(Color.BLUE);
067gc.fillRect(75,75,100,100);
068 
069root.getChildren().add(canvas);
070 * </pre>
071 * </p>
072 *
073 * @since 2.2
074 */
075public class Canvas extends Node {
076    private static final int DEFAULT_BUF_SIZE = 1024;
077
078    private GrowableDataBuffer<Object> empty;
079    private GrowableDataBuffer<Object> full;
080
081    private GraphicsContext theContext;
082
083    /**
084     * Creates an empty instance of Canvas.
085     */
086    public Canvas() {
087        this(0, 0);
088    }
089
090    /**
091     * Creates a new instance of Canvas with the given size.
092     * 
093     * @param width width of the canvas
094     * @param height height of the canvas
095     */
096    public Canvas(double width, double height) {
097        setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
098        setWidth(width);
099        setHeight(height);
100    }
101
102    GrowableDataBuffer<Object> getBuffer() {
103        impl_markDirty(DirtyBits.NODE_CONTENTS);
104        if (empty == null) {
105            empty = new GrowableDataBuffer<Object>(DEFAULT_BUF_SIZE);
106        }
107        return empty;
108    }
109
110    /**
111     * returns the {@code GraphicsContext} associated with this {@code Canvas}.
112     */
113    public GraphicsContext getGraphicsContext2D() {
114        if (theContext == null) {
115            theContext = new GraphicsContext(this);
116        }
117        return theContext;
118    }
119
120    /**
121     * Defines the width of the canvas.
122     *
123     * @profile common
124     * @defaultvalue 0.0
125     */
126    private DoubleProperty width;
127
128    public final void setWidth(double value) {
129        widthProperty().set(value);
130    }
131
132    public final double getWidth() {
133        return width == null ? 0.0 : width.get();
134    }
135
136    public final DoubleProperty widthProperty() {
137        if (width == null) {
138            width = new DoublePropertyBase() {
139
140                @Override
141                public void invalidated() {
142                    impl_markDirty(DirtyBits.NODE_GEOMETRY);
143                    impl_geomChanged();
144                }
145
146                @Override
147                public Object getBean() {
148                    return Canvas.this;
149                }
150
151                @Override
152                public String getName() {
153                    return "width";
154                }
155            };
156        }
157        return width;
158    }
159
160    /**
161     * Defines the height of the canvas.
162     *
163     * @profile common
164     * @defaultvalue 0.0
165     */
166    private DoubleProperty height;
167
168    public final void setHeight(double value) {
169        heightProperty().set(value);
170    }
171
172    public final double getHeight() {
173        return height == null ? 0.0 : height.get();
174    }
175
176    public final DoubleProperty heightProperty() {
177        if (height == null) {
178            height = new DoublePropertyBase() {
179
180                @Override
181                public void invalidated() {
182                    impl_markDirty(DirtyBits.NODE_GEOMETRY);
183                    impl_geomChanged();
184                }
185
186                @Override
187                public Object getBean() {
188                    return Canvas.this;
189                }
190
191                @Override
192                public String getName() {
193                    return "height";
194                }
195            };
196        }
197        return height;
198    }
199
200    /**
201     * @treatAsPrivate implementation detail
202     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
203     */
204    @Deprecated
205    @Override protected PGNode impl_createPGNode() {
206        return Toolkit.getToolkit().createPGCanvas();
207    }
208
209    PGCanvas getPGCanvas() {
210        return (PGCanvas) impl_getPGNode();
211    }
212
213    /**
214     * @treatAsPrivate implementation detail
215     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
216     */
217    @Deprecated
218    @Override
219    public void impl_updatePG() {
220        super.impl_updatePG();
221        if (impl_isDirty(DirtyBits.NODE_GEOMETRY)) {
222            PGCanvas peer = getPGCanvas();
223            peer.updateBounds((float)getWidth(),
224                              (float)getHeight());
225        }
226        if (impl_isDirty(DirtyBits.NODE_CONTENTS)) {
227            PGCanvas peer = getPGCanvas();
228            if (empty != null && empty.position() > 0) {
229                 peer.updateRendering(empty);
230                 if (full != null) {
231                    full.resetForWrite();
232                 }
233                 GrowableDataBuffer tmp = empty;
234                 empty = full;
235                 full = tmp;
236            }
237        }
238    }
239    /**
240     * @treatAsPrivate implementation detail
241     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
242     */
243    @Deprecated
244    @Override
245    protected boolean impl_computeContains(double localX, double localY) {
246        double w = getWidth();
247        double h = getHeight();
248        return (w > 0 && h > 0 &&
249                localX >= 0 && localY >= 0 &&
250                localX <  w && localY <  h);
251    }
252
253    /**
254     * @treatAsPrivate implementation detail
255     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
256     */
257    @Deprecated
258    @Override
259    public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) {
260        bounds = new RectBounds(0f, 0f, (float) getWidth(), (float) getHeight());  
261        bounds = tx.transform(bounds, bounds);
262        return bounds;
263    }
264
265    /**
266     * @treatAsPrivate implementation detail
267     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
268     */
269    @Deprecated
270    @Override
271    public Object impl_processMXNode(MXNodeAlgorithm alg,
272                                     MXNodeAlgorithmContext ctx) {
273        return alg.processLeafNode(this, ctx);
274    }
275}