Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 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.shape;
027
028import javafx.beans.property.ObjectProperty;
029import javafx.beans.property.ObjectPropertyBase;
030import javafx.beans.property.StringProperty;
031import javafx.beans.property.StringPropertyBase;
032import com.sun.javafx.Logging;
033import com.sun.javafx.geom.Path2D;
034import com.sun.javafx.scene.DirtyBits;
035import com.sun.javafx.sg.PGNode;
036import com.sun.javafx.sg.PGSVGPath;
037import com.sun.javafx.tk.Toolkit;
038import javafx.scene.paint.Paint;
039
040/**
041 * The {@code SVGPath} class represents a simple shape that is constructed by
042 * parsing SVG path data from a String.
043 *
044<PRE>
045import javafx.scene.shape.*;
046
047SVGPath svg = new SVGPath();
048svg.setContent("M40,60 C42,48 44,30 25,32");
049</PRE>
050 */
051public  class SVGPath extends Shape {
052    /**
053     * Defines the filling rule constant for determining the interior of the path.
054     * The value must be one of the following constants:
055     * {@code FillRile.EVEN_ODD} or {@code FillRule.NON_ZERO}.
056     * The default value is {@code FillRule.NON_ZERO}.
057     *
058     * @defaultValue FillRule.NON_ZERO
059     */
060    private ObjectProperty<FillRule> fillRule;
061
062    private Path2D path2d;
063
064    public final void setFillRule(FillRule value) {
065        if (fillRule != null || value != FillRule.NON_ZERO) {
066            fillRuleProperty().set(value);
067        }
068    }
069
070    public final FillRule getFillRule() {
071        return fillRule == null ? FillRule.NON_ZERO : fillRule.get();
072    }
073
074    public final ObjectProperty<FillRule> fillRuleProperty() {
075        if (fillRule == null) {
076            fillRule = new ObjectPropertyBase<FillRule>(FillRule.NON_ZERO) {
077
078                @Override
079                public void invalidated() {
080                    impl_markDirty(DirtyBits.SHAPE_FILLRULE);
081                    impl_geomChanged();
082                }
083
084                @Override
085                public Object getBean() {
086                    return SVGPath.this;
087                }
088
089                @Override
090                public String getName() {
091                    return "fillRule";
092                }
093            };
094        }
095        return fillRule;
096    }
097
098    /**
099     * Defines the SVG Path encoded string as specified at:
100     * <a href="http://www.w3.org/TR/SVG/paths.html">http://www.w3.org/TR/SVG/paths.html</a>.
101     *
102     * @defaultValue empty string
103     */
104    private StringProperty content;
105
106
107    public final void setContent(String value) {
108        contentProperty().set(value);
109    }
110
111    public final String getContent() {
112        return content == null ? "" : content.get();
113    }
114
115    public final StringProperty contentProperty() {
116        if (content == null) {
117            content = new StringPropertyBase("") {
118
119                @Override
120                public void invalidated() {
121                    impl_markDirty(DirtyBits.NODE_CONTENTS);
122                    impl_geomChanged();
123                    path2d = null;
124                }
125
126                @Override
127                public Object getBean() {
128                    return SVGPath.this;
129                }
130
131                @Override
132                public String getName() {
133                    return "content";
134                }
135            };
136        }
137        return content;
138    }
139
140    private Object svgPathObject;
141
142    /**
143     * @treatAsPrivate implementation detail
144     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
145     */
146    @Deprecated
147    @Override
148    protected PGNode impl_createPGNode() {
149        return Toolkit.getToolkit().createPGSVGPath();
150    }
151
152    /**
153     * @treatAsPrivate implementation detail
154     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
155     */
156    @Deprecated
157    public PGSVGPath impl_getPGSVGPath() {
158        return (PGSVGPath)impl_getPGNode();
159    }
160
161    /**
162     * @treatAsPrivate implementation detail
163     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
164     */
165    @Deprecated
166    @Override
167    public Path2D impl_configShape() {
168        if (path2d == null) {
169            path2d = createSVGPath2D();
170        } else {
171            path2d.setWindingRule(getFillRule() == FillRule.NON_ZERO ?
172                                  Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD);
173        }
174
175        return path2d;
176    }
177
178    /**
179     * @treatAsPrivate implementation detail
180     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
181     */
182    @Deprecated
183    @Override
184    public void impl_updatePG() {
185        super.impl_updatePG();
186
187        if (impl_isDirty(DirtyBits.SHAPE_FILLRULE) ||
188            impl_isDirty(DirtyBits.NODE_CONTENTS))
189        {
190            if (impl_getPGSVGPath().acceptsPath2dOnUpdate()) {
191                if (svgPathObject == null) {
192                    svgPathObject = new Path2D();
193                }
194                Path2D tempPathObject = (Path2D) svgPathObject;
195                tempPathObject.setTo(impl_configShape());
196            } else {
197                svgPathObject = createSVGPathObject();
198            }
199            impl_getPGSVGPath().setContent(svgPathObject);
200        }
201    }
202
203    /**
204     * Returns a string representation of this {@code SVGPath} object.
205     * @return a string representation of this {@code SVGPath} object.
206     */
207    @Override
208    public String toString() {
209        final StringBuilder sb = new StringBuilder("SVGPath[");
210
211        String id = getId();
212        if (id != null) {
213            sb.append("id=").append(id).append(", ");
214        }
215
216        sb.append("content=\"").append(getContent()).append("\"");
217
218        sb.append(", fill=").append(getFill());
219        sb.append(", fillRule=").append(getFillRule());
220
221        Paint stroke = getStroke();
222        if (stroke != null) {
223            sb.append(", stroke=").append(stroke);
224            sb.append(", strokeWidth=").append(getStrokeWidth());
225        }
226
227        return sb.append("]").toString();
228    }
229
230    private Path2D createSVGPath2D() {
231        try {
232            return Toolkit.getToolkit().createSVGPath2D(this);
233        } catch (final RuntimeException e) {
234            Logging.getJavaFXLogger().warning(
235                    "Failed to configure svg path \"{0}\": {1}",
236                    getContent(), e.getMessage());
237
238            return Toolkit.getToolkit().createSVGPath2D(new SVGPath());
239        }
240    }
241
242    private Object createSVGPathObject() {
243        try {
244            return Toolkit.getToolkit().createSVGPathObject(this);
245        } catch (final RuntimeException e) {
246            Logging.getJavaFXLogger().warning(
247                    "Failed to configure svg path \"{0}\": {1}",
248                    getContent(), e.getMessage());
249
250            return Toolkit.getToolkit().createSVGPathObject(new SVGPath());
251        }
252    }
253}