53 ellipse.setCenterY(50.0f); 54 ellipse.setRadiusX(50.0f); 55 ellipse.setRadiusY(25.0f); 56 </PRE> 57 * @since JavaFX 2.0 58 */ 59 public class Ellipse extends Shape { 60 static { 61 EllipseHelper.setEllipseAccessor(new EllipseHelper.EllipseAccessor() { 62 @Override 63 public NGNode doCreatePeer(Node node) { 64 return ((Ellipse) node).doCreatePeer(); 65 } 66 67 @Override 68 public void doUpdatePeer(Node node) { 69 ((Ellipse) node).doUpdatePeer(); 70 } 71 72 @Override 73 public com.sun.javafx.geom.Shape doConfigShape(Shape shape) { 74 return ((Ellipse) shape).doConfigShape(); 75 } 76 }); 77 } 78 79 private final Ellipse2D shape = new Ellipse2D(); 80 81 private static final int NON_RECTILINEAR_TYPE_MASK = ~( 82 BaseTransform.TYPE_TRANSLATION | 83 BaseTransform.TYPE_QUADRANT_ROTATION | 84 BaseTransform.TYPE_MASK_SCALE | 85 BaseTransform.TYPE_FLIP); 86 87 { 88 // To initialize the class helper at the begining each constructor of this class 89 EllipseHelper.initHelper(this); 90 } 91 92 /** 125 */ 126 private DoubleProperty centerX; 127 128 public final void setCenterX(double value) { 129 if (centerX != null || value != 0.0) { 130 centerXProperty().set(value); 131 } 132 } 133 134 public final double getCenterX() { 135 return centerX == null ? 0.0 : centerX.get(); 136 } 137 138 public final DoubleProperty centerXProperty() { 139 if (centerX == null) { 140 centerX = new DoublePropertyBase() { 141 142 @Override 143 public void invalidated() { 144 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 145 impl_geomChanged(); 146 } 147 148 @Override 149 public Object getBean() { 150 return Ellipse.this; 151 } 152 153 @Override 154 public String getName() { 155 return "centerX"; 156 } 157 }; 158 } 159 return centerX; 160 } 161 162 /** 163 * Defines the vertical position of the center of the ellipse in pixels. 164 * 165 * @defaultValue 0.0 166 */ 167 private DoubleProperty centerY; 168 169 public final void setCenterY(double value) { 170 if (centerY != null || value != 0.0) { 171 centerYProperty().set(value); 172 } 173 } 174 175 public final double getCenterY() { 176 return centerY == null ? 0.0 : centerY.get(); 177 } 178 179 public final DoubleProperty centerYProperty() { 180 if (centerY == null) { 181 centerY = new DoublePropertyBase() { 182 183 @Override 184 public void invalidated() { 185 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 186 impl_geomChanged(); 187 } 188 189 @Override 190 public Object getBean() { 191 return Ellipse.this; 192 } 193 194 @Override 195 public String getName() { 196 return "centerY"; 197 } 198 }; 199 } 200 return centerY; 201 } 202 203 /** 204 * Defines the width of the ellipse in pixels. 205 * 206 * @defaultValue 0.0 207 */ 208 private final DoubleProperty radiusX = new DoublePropertyBase() { 209 210 @Override 211 public void invalidated() { 212 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 213 impl_geomChanged(); 214 } 215 216 @Override 217 public Object getBean() { 218 return Ellipse.this; 219 } 220 221 @Override 222 public String getName() { 223 return "radiusX"; 224 } 225 }; 226 227 public final void setRadiusX(double value) { 228 radiusX.set(value); 229 } 230 231 public final double getRadiusX() { 232 return radiusX.get(); 233 } 234 235 public final DoubleProperty radiusXProperty() { 236 return radiusX; 237 } 238 239 /** 240 * Defines the height of the ellipse in pixels. 241 * 242 * @defaultValue 0.0 243 */ 244 private final DoubleProperty radiusY = new DoublePropertyBase() { 245 246 @Override 247 public void invalidated() { 248 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 249 impl_geomChanged(); 250 } 251 252 @Override 253 public Object getBean() { 254 return Ellipse.this; 255 } 256 257 @Override 258 public String getName() { 259 return "radiusY"; 260 } 261 }; 262 263 public final void setRadiusY(double value) { 264 radiusY.set(value); 265 } 266 267 public final double getRadiusY() { 268 return radiusY.get(); 269 } 278 private NGNode doCreatePeer() { 279 return new NGEllipse(); 280 } 281 282 /** 283 */ 284 @Override StrokeLineJoin convertLineJoin(StrokeLineJoin t) { 285 // The MITER join style can produce anomalous results for very thin or 286 // very wide ellipses when the bezier curves that approximate the arcs 287 // become so distorted that they shoot out MITER-like extensions. This 288 // effect complicates matters because it makes the ellipses very non-round, 289 // and also because it means we might have to pad the bounds to account 290 // for this rare and unpredictable circumstance. 291 // To avoid the problem, we set the Join style to BEVEL for any 292 // ellipse. The BEVEL join style is more predictable for 293 // anomalous angles and is the simplest join style to compute in 294 // the stroking code. 295 return StrokeLineJoin.BEVEL; 296 } 297 298 /** 299 * @treatAsPrivate implementation detail 300 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 301 */ 302 @Deprecated 303 @Override 304 public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) { 305 // if there is no fill or stroke, then there are no bounds. The bounds 306 // must be marked empty in this case to distinguish it from 0,0,0,0 307 // which would actually contribute to the bounds of a group. 308 if (getMode() == NGShape.Mode.EMPTY) { 309 return bounds.makeEmpty(); 310 } 311 if ((tx.getType() & NON_RECTILINEAR_TYPE_MASK) != 0) { 312 return computeShapeBounds(bounds, tx, ShapeHelper.configShape(this)); 313 } 314 315 // compute the x, y, width and height of the ellipse 316 final double x = getCenterX() - getRadiusX(); 317 final double y = getCenterY() - getRadiusY(); 318 final double width = 2.0f * getRadiusX(); 319 final double height = 2.0f * getRadiusY(); 320 double upad; 321 double dpad; 322 if (getMode() == NGShape.Mode.FILL || getStrokeType() == StrokeType.INSIDE) { 323 upad = dpad = 0.0f; 324 } else { | 53 ellipse.setCenterY(50.0f); 54 ellipse.setRadiusX(50.0f); 55 ellipse.setRadiusY(25.0f); 56 </PRE> 57 * @since JavaFX 2.0 58 */ 59 public class Ellipse extends Shape { 60 static { 61 EllipseHelper.setEllipseAccessor(new EllipseHelper.EllipseAccessor() { 62 @Override 63 public NGNode doCreatePeer(Node node) { 64 return ((Ellipse) node).doCreatePeer(); 65 } 66 67 @Override 68 public void doUpdatePeer(Node node) { 69 ((Ellipse) node).doUpdatePeer(); 70 } 71 72 @Override 73 public BaseBounds doComputeGeomBounds(Node node, 74 BaseBounds bounds, BaseTransform tx) { 75 return ((Ellipse) node).doComputeGeomBounds(bounds, tx); 76 } 77 78 @Override 79 public com.sun.javafx.geom.Shape doConfigShape(Shape shape) { 80 return ((Ellipse) shape).doConfigShape(); 81 } 82 }); 83 } 84 85 private final Ellipse2D shape = new Ellipse2D(); 86 87 private static final int NON_RECTILINEAR_TYPE_MASK = ~( 88 BaseTransform.TYPE_TRANSLATION | 89 BaseTransform.TYPE_QUADRANT_ROTATION | 90 BaseTransform.TYPE_MASK_SCALE | 91 BaseTransform.TYPE_FLIP); 92 93 { 94 // To initialize the class helper at the begining each constructor of this class 95 EllipseHelper.initHelper(this); 96 } 97 98 /** 131 */ 132 private DoubleProperty centerX; 133 134 public final void setCenterX(double value) { 135 if (centerX != null || value != 0.0) { 136 centerXProperty().set(value); 137 } 138 } 139 140 public final double getCenterX() { 141 return centerX == null ? 0.0 : centerX.get(); 142 } 143 144 public final DoubleProperty centerXProperty() { 145 if (centerX == null) { 146 centerX = new DoublePropertyBase() { 147 148 @Override 149 public void invalidated() { 150 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 151 NodeHelper.geomChanged(Ellipse.this); 152 } 153 154 @Override 155 public Object getBean() { 156 return Ellipse.this; 157 } 158 159 @Override 160 public String getName() { 161 return "centerX"; 162 } 163 }; 164 } 165 return centerX; 166 } 167 168 /** 169 * Defines the vertical position of the center of the ellipse in pixels. 170 * 171 * @defaultValue 0.0 172 */ 173 private DoubleProperty centerY; 174 175 public final void setCenterY(double value) { 176 if (centerY != null || value != 0.0) { 177 centerYProperty().set(value); 178 } 179 } 180 181 public final double getCenterY() { 182 return centerY == null ? 0.0 : centerY.get(); 183 } 184 185 public final DoubleProperty centerYProperty() { 186 if (centerY == null) { 187 centerY = new DoublePropertyBase() { 188 189 @Override 190 public void invalidated() { 191 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 192 NodeHelper.geomChanged(Ellipse.this); 193 } 194 195 @Override 196 public Object getBean() { 197 return Ellipse.this; 198 } 199 200 @Override 201 public String getName() { 202 return "centerY"; 203 } 204 }; 205 } 206 return centerY; 207 } 208 209 /** 210 * Defines the width of the ellipse in pixels. 211 * 212 * @defaultValue 0.0 213 */ 214 private final DoubleProperty radiusX = new DoublePropertyBase() { 215 216 @Override 217 public void invalidated() { 218 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 219 NodeHelper.geomChanged(Ellipse.this); 220 } 221 222 @Override 223 public Object getBean() { 224 return Ellipse.this; 225 } 226 227 @Override 228 public String getName() { 229 return "radiusX"; 230 } 231 }; 232 233 public final void setRadiusX(double value) { 234 radiusX.set(value); 235 } 236 237 public final double getRadiusX() { 238 return radiusX.get(); 239 } 240 241 public final DoubleProperty radiusXProperty() { 242 return radiusX; 243 } 244 245 /** 246 * Defines the height of the ellipse in pixels. 247 * 248 * @defaultValue 0.0 249 */ 250 private final DoubleProperty radiusY = new DoublePropertyBase() { 251 252 @Override 253 public void invalidated() { 254 NodeHelper.markDirty(Ellipse.this, DirtyBits.NODE_GEOMETRY); 255 NodeHelper.geomChanged(Ellipse.this); 256 } 257 258 @Override 259 public Object getBean() { 260 return Ellipse.this; 261 } 262 263 @Override 264 public String getName() { 265 return "radiusY"; 266 } 267 }; 268 269 public final void setRadiusY(double value) { 270 radiusY.set(value); 271 } 272 273 public final double getRadiusY() { 274 return radiusY.get(); 275 } 284 private NGNode doCreatePeer() { 285 return new NGEllipse(); 286 } 287 288 /** 289 */ 290 @Override StrokeLineJoin convertLineJoin(StrokeLineJoin t) { 291 // The MITER join style can produce anomalous results for very thin or 292 // very wide ellipses when the bezier curves that approximate the arcs 293 // become so distorted that they shoot out MITER-like extensions. This 294 // effect complicates matters because it makes the ellipses very non-round, 295 // and also because it means we might have to pad the bounds to account 296 // for this rare and unpredictable circumstance. 297 // To avoid the problem, we set the Join style to BEVEL for any 298 // ellipse. The BEVEL join style is more predictable for 299 // anomalous angles and is the simplest join style to compute in 300 // the stroking code. 301 return StrokeLineJoin.BEVEL; 302 } 303 304 /* 305 * Note: This method MUST only be called via its accessor method. 306 */ 307 private BaseBounds doComputeGeomBounds(BaseBounds bounds, BaseTransform tx) { 308 // if there is no fill or stroke, then there are no bounds. The bounds 309 // must be marked empty in this case to distinguish it from 0,0,0,0 310 // which would actually contribute to the bounds of a group. 311 if (getMode() == NGShape.Mode.EMPTY) { 312 return bounds.makeEmpty(); 313 } 314 if ((tx.getType() & NON_RECTILINEAR_TYPE_MASK) != 0) { 315 return computeShapeBounds(bounds, tx, ShapeHelper.configShape(this)); 316 } 317 318 // compute the x, y, width and height of the ellipse 319 final double x = getCenterX() - getRadiusX(); 320 final double y = getCenterY() - getRadiusY(); 321 final double width = 2.0f * getRadiusX(); 322 final double height = 2.0f * getRadiusY(); 323 double upad; 324 double dpad; 325 if (getMode() == NGShape.Mode.FILL || getStrokeType() == StrokeType.INSIDE) { 326 upad = dpad = 0.0f; 327 } else { |