/* * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javafx.scene.shape; import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoublePropertyBase; import javafx.css.CssMetaData; import javafx.css.Styleable; import javafx.css.StyleableDoubleProperty; import javafx.css.StyleableProperty; import javafx.scene.paint.Paint; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javafx.css.converter.SizeConverter; import com.sun.javafx.geom.BaseBounds; import com.sun.javafx.geom.RoundRectangle2D; import com.sun.javafx.geom.transform.BaseTransform; import com.sun.javafx.scene.DirtyBits; import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.scene.shape.RectangleHelper; import com.sun.javafx.scene.shape.ShapeHelper; import com.sun.javafx.sg.prism.NGNode; import com.sun.javafx.sg.prism.NGRectangle; import com.sun.javafx.sg.prism.NGShape; import javafx.scene.Node; /** * The {@code Rectangle} class defines a rectangle * with the specified size and location. By default the rectangle * has sharp corners. Rounded corners can be specified by setting both of * the arcWidth and arcHeight properties to positive values {@code (> 0.0)}. *
Example code: the following code creates a rectangle with 20 pixel * rounded corners.
*import javafx.scene.shape.*; Rectangle r = new Rectangle(); r.setX(50); r.setY(50); r.setWidth(200); r.setHeight(100); r.setArcWidth(20); r.setArcHeight(20);* @since JavaFX 2.0 */ public class Rectangle extends Shape { static { RectangleHelper.setRectangleAccessor(new RectangleHelper.RectangleAccessor() { @Override public NGNode doCreatePeer(Node node) { return ((Rectangle) node).doCreatePeer(); } @Override public void doUpdatePeer(Node node) { ((Rectangle) node).doUpdatePeer(); } @Override public BaseBounds doComputeGeomBounds(Node node, BaseBounds bounds, BaseTransform tx) { return ((Rectangle) node).doComputeGeomBounds(bounds, tx); } @Override public com.sun.javafx.geom.Shape doConfigShape(Shape shape) { return ((Rectangle) shape).doConfigShape(); } }); } private final RoundRectangle2D shape = new RoundRectangle2D(); private static final int NON_RECTILINEAR_TYPE_MASK = ~( BaseTransform.TYPE_TRANSLATION | BaseTransform.TYPE_MASK_SCALE | BaseTransform.TYPE_QUADRANT_ROTATION | BaseTransform.TYPE_FLIP); { // To initialize the class helper at the begining each constructor of this class RectangleHelper.initHelper(this); } /** * Creates an empty instance of Rectangle. */ public Rectangle() { } /** * Creates a new instance of Rectangle with the given size. * @param width width of the rectangle * @param height height of the rectangle */ public Rectangle(double width, double height) { setWidth(width); setHeight(height); } /** * Creates a new instance of Rectangle with the given size and fill. * @param width width of the rectangle * @param height height of the rectangle * @param fill determines how to fill the interior of the rectangle */ public Rectangle(double width, double height, Paint fill) { setWidth(width); setHeight(height); setFill(fill); } /** * Creates a new instance of Rectangle with the given position and size. * @param x horizontal position of the rectangle * @param y vertical position of the rectangle * @param width width of the rectangle * @param height height of the rectangle */ public Rectangle(double x, double y, double width, double height) { this(width, height); setX(x); setY(y); } /** * Defines the X coordinate of the upper-left corner of the rectangle. * * @defaultValue 0.0 */ private DoubleProperty x; public final void setX(double value) { if (x != null || value != 0.0) { xProperty().set(value); } } public final double getX() { return x == null ? 0.0 : x.get(); } public final DoubleProperty xProperty() { if (x == null) { x = new DoublePropertyBase() { @Override public void invalidated() { NodeHelper.markDirty(Rectangle.this, DirtyBits.NODE_GEOMETRY); NodeHelper.geomChanged(Rectangle.this); } @Override public Object getBean() { return Rectangle.this; } @Override public String getName() { return "x"; } }; } return x; } /** * Defines the Y coordinate of the upper-left corner of the rectangle. * * @defaultValue 0.0 */ private DoubleProperty y; public final void setY(double value) { if (y != null || value != 0.0) { yProperty().set(value); } } public final double getY() { return y == null ? 0.0 : y.get(); } public final DoubleProperty yProperty() { if (y == null) { y = new DoublePropertyBase() { @Override public void invalidated() { NodeHelper.markDirty(Rectangle.this, DirtyBits.NODE_GEOMETRY); NodeHelper.geomChanged(Rectangle.this); } @Override public Object getBean() { return Rectangle.this; } @Override public String getName() { return "y"; } }; } return y; } /** * Defines the width of the rectangle. * * @defaultValue 0.0 */ private final DoubleProperty width = new DoublePropertyBase() { @Override public void invalidated() { NodeHelper.markDirty(Rectangle.this, DirtyBits.NODE_GEOMETRY); NodeHelper.geomChanged(Rectangle.this); } @Override public Object getBean() { return Rectangle.this; } @Override public String getName() { return "width"; } }; public final void setWidth(double value) { width.set(value); } public final double getWidth() { return width.get(); } public final DoubleProperty widthProperty() { return width; } /** * Defines the height of the rectangle. * * @defaultValue 0.0 */ private final DoubleProperty height = new DoublePropertyBase() { @Override public void invalidated() { NodeHelper.markDirty(Rectangle.this, DirtyBits.NODE_GEOMETRY); NodeHelper.geomChanged(Rectangle.this); } @Override public Object getBean() { return Rectangle.this; } @Override public String getName() { return "height"; } }; public final void setHeight(double value) { height.set(value); } public final double getHeight() { return height.get(); } public final DoubleProperty heightProperty() { return height; } /** * Defines the horizontal diameter of the arc * at the four corners of the rectangle. * The rectangle will have rounded corners if and only if both of * the arc width and arc height properties are greater than 0.0. * * @defaultValue 0.0 */ private DoubleProperty arcWidth; public final void setArcWidth(double value) { if (arcWidth != null || value != 0.0) { arcWidthProperty().set(value); } } public final double getArcWidth() { return arcWidth == null ? 0.0 : arcWidth.get(); } public final DoubleProperty arcWidthProperty() { if (arcWidth == null) { arcWidth = new StyleableDoubleProperty() { @Override public void invalidated() { NodeHelper.markDirty(Rectangle.this, DirtyBits.NODE_GEOMETRY); } @Override public CssMetaData