1 /* 2 * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.shape; 27 28 29 import com.sun.javafx.geom.QuadCurve2D; 30 import com.sun.javafx.scene.DirtyBits; 31 import com.sun.javafx.scene.NodeHelper; 32 import com.sun.javafx.scene.shape.QuadCurveHelper; 33 import com.sun.javafx.sg.prism.NGNode; 34 import com.sun.javafx.sg.prism.NGQuadCurve; 35 import javafx.beans.property.DoubleProperty; 36 import javafx.beans.property.DoublePropertyBase; 37 import javafx.scene.Node; 38 import javafx.scene.paint.Paint; 39 40 41 /** 42 * The {@code Quadcurve} class defines a quadratic Bézier parametric curve 43 * segment in (x,y) coordinate space. Drawing a curve that intersects both the 44 * specified coordinates {@code (startX, startY)} and {@code (endX, enfY)}, 45 * using the specified point {@code (controlX, controlY)} 46 * as Bézier control point. 47 * 48 <PRE> 49 import javafx.scene.shape.*; 50 51 QuadCurve quad = new QuadCurve(); 52 quad.setStartX(0.0f); 53 quad.setStartY(50.0f); 54 quad.setEndX(50.0f); 55 quad.setEndY(50.0f); 56 quad.setControlX(25.0f); 57 quad.setControlY(0.0f); 58 </PRE> 59 * @since JavaFX 2.0 60 */ 61 public class QuadCurve extends Shape { 62 static { 63 QuadCurveHelper.setQuadCurveAccessor(new QuadCurveHelper.QuadCurveAccessor() { 64 @Override 65 public NGNode doCreatePeer(Node node) { 66 return ((QuadCurve) node).doCreatePeer(); 67 } 68 69 @Override 70 public void doUpdatePeer(Node node) { 71 ((QuadCurve) node).doUpdatePeer(); 72 } 73 74 @Override 75 public com.sun.javafx.geom.Shape doConfigShape(Shape shape) { 76 return ((QuadCurve) shape).doConfigShape(); 77 } 78 }); 79 } 80 81 private final QuadCurve2D shape = new QuadCurve2D(); 82 83 { 84 // To initialize the class helper at the begining each constructor of this class 85 QuadCurveHelper.initHelper(this); 86 } 87 88 /** 89 * Creates an empty instance of QuadCurve. 90 */ 91 public QuadCurve() { 92 } 93 94 /** 95 * Creates a new instance of QuadCurve. 96 * @param startX the X coordinate of the start point 97 * @param startY the Y coordinate of the start point 98 * @param controlX the X coordinate of the control point 99 * @param controlY the Y coordinate of the control point 100 * @param endX the X coordinate of the end point 101 * @param endY the Y coordinate of the end point 102 */ 103 public QuadCurve(double startX, double startY, double controlX, double controlY, double endX, double endY) { 104 setStartX(startX); 105 setStartY(startY); 106 setControlX(controlX); 107 setControlY(controlY); 108 setEndX(endX); 109 setEndY(endY); 110 } 111 112 /** 113 * Defines the X coordinate of the start point 114 * of the quadratic curve segment. 115 * 116 * @defaultValue 0.0 117 */ 118 private DoubleProperty startX; 119 120 public final void setStartX(double value) { 121 if (startX != null || value != 0.0) { 122 startXProperty().set(value); 123 } 124 } 125 126 public final double getStartX() { 127 return startX == null ? 0.0 : startX.get(); 128 } 129 130 public final DoubleProperty startXProperty() { 131 if (startX == null) { 132 startX = new DoublePropertyBase() { 133 134 @Override 135 public void invalidated() { 136 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 137 impl_geomChanged(); 138 } 139 140 @Override 141 public Object getBean() { 142 return QuadCurve.this; 143 } 144 145 @Override 146 public String getName() { 147 return "startX"; 148 } 149 }; 150 } 151 return startX; 152 } 153 154 /** 155 * Defines the Y coordinate of the start point 156 * of the quadratic curve segment. 157 * 158 * @defaultValue 0.0 159 */ 160 private DoubleProperty startY; 161 162 public final void setStartY(double value) { 163 if (startY != null || value != 0.0) { 164 startYProperty().set(value); 165 } 166 } 167 168 public final double getStartY() { 169 return startY == null ? 0.0 : startY.get(); 170 } 171 172 public final DoubleProperty startYProperty() { 173 if (startY == null) { 174 startY = new DoublePropertyBase() { 175 176 @Override 177 public void invalidated() { 178 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 179 impl_geomChanged(); 180 } 181 182 @Override 183 public Object getBean() { 184 return QuadCurve.this; 185 } 186 187 @Override 188 public String getName() { 189 return "startY"; 190 } 191 }; 192 } 193 return startY; 194 } 195 196 /** 197 * Defines the X coordinate of the control point 198 * of the quadratic curve segment. 199 * 200 * @defaultValue 0.0 201 */ 202 private DoubleProperty controlX = new DoublePropertyBase() { 203 204 @Override 205 public void invalidated() { 206 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 207 impl_geomChanged(); 208 } 209 210 @Override 211 public Object getBean() { 212 return QuadCurve.this; 213 } 214 215 @Override 216 public String getName() { 217 return "controlX"; 218 } 219 }; 220 221 public final void setControlX(double value) { 222 controlX.set(value); 223 } 224 225 public final double getControlX() { 226 return controlX.get(); 227 } 228 229 public final DoubleProperty controlXProperty() { 230 return controlX; 231 } 232 233 /** 234 * Defines the Y coordinate of the control point 235 * of the quadratic curve segment. 236 * 237 * @defaultValue 0.0 238 */ 239 private DoubleProperty controlY = new DoublePropertyBase() { 240 241 @Override 242 public void invalidated() { 243 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 244 impl_geomChanged(); 245 } 246 247 @Override 248 public Object getBean() { 249 return QuadCurve.this; 250 } 251 252 @Override 253 public String getName() { 254 return "controlY"; 255 } 256 }; 257 258 259 public final void setControlY(double value) { 260 controlY.set(value); 261 } 262 263 public final double getControlY() { 264 return controlY.get(); 265 } 266 267 public final DoubleProperty controlYProperty() { 268 return controlY; 269 } 270 271 /** 272 * Defines the X coordinate of the end point 273 * of the quadratic curve segment. 274 * 275 * @defaultValue 0.0 276 */ 277 private DoubleProperty endX; 278 279 280 public final void setEndX(double value) { 281 if (endX != null || value != 0.0) { 282 endXProperty().set(value); 283 } 284 } 285 286 public final double getEndX() { 287 return endX == null ? 0.0 : endX.get(); 288 } 289 290 public final DoubleProperty endXProperty() { 291 if (endX == null) { 292 endX = new DoublePropertyBase() { 293 294 @Override 295 public void invalidated() { 296 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 297 impl_geomChanged(); 298 } 299 300 @Override 301 public Object getBean() { 302 return QuadCurve.this; 303 } 304 305 @Override 306 public String getName() { 307 return "endX"; 308 } 309 }; 310 } 311 return endX; 312 } 313 314 /** 315 * Defines the Y coordinate of the end point 316 * of the quadratic curve segment. 317 * 318 * @defaultValue 0.0 319 */ 320 private DoubleProperty endY; 321 322 public final void setEndY(double value) { 323 if (endY != null || value != 0.0) { 324 endYProperty().set(value); 325 } 326 } 327 328 public final double getEndY() { 329 return endY == null ? 0.0 : endY.get(); 330 } 331 332 public final DoubleProperty endYProperty() { 333 if (endY == null) { 334 endY = new DoublePropertyBase() { 335 336 @Override 337 public void invalidated() { 338 NodeHelper.markDirty(QuadCurve.this, DirtyBits.NODE_GEOMETRY); 339 impl_geomChanged(); 340 } 341 342 @Override 343 public Object getBean() { 344 return QuadCurve.this; 345 } 346 347 @Override 348 public String getName() { 349 return "endY"; 350 } 351 }; 352 } 353 return endY; 354 } 355 356 /* 357 * Note: This method MUST only be called via its accessor method. 358 */ 359 private NGNode doCreatePeer() { 360 return new NGQuadCurve(); 361 } 362 363 /* 364 * Note: This method MUST only be called via its accessor method. 365 */ 366 private QuadCurve2D doConfigShape() { 367 shape.x1 = (float)getStartX(); 368 shape.y1 = (float)getStartY(); 369 shape.ctrlx = (float)getControlX(); 370 shape.ctrly = (float)getControlY(); 371 shape.x2 = (float)getEndX(); 372 shape.y2 = (float)getEndY(); 373 return shape; 374 } 375 376 /* 377 * Note: This method MUST only be called via its accessor method. 378 */ 379 private void doUpdatePeer() { 380 if (NodeHelper.isDirty(this, DirtyBits.NODE_GEOMETRY)) { 381 final NGQuadCurve peer = NodeHelper.getPeer(this); 382 peer.updateQuadCurve((float)getStartX(), 383 (float)getStartY(), 384 (float)getEndX(), 385 (float)getEndY(), 386 (float)getControlX(), 387 (float)getControlY()); 388 } 389 } 390 391 /** 392 * Returns a string representation of this {@code QuadCurve} object. 393 * @return a string representation of this {@code QuadCurve} object. 394 */ 395 @Override 396 public String toString() { 397 final StringBuilder sb = new StringBuilder("QuadCurve["); 398 399 String id = getId(); 400 if (id != null) { 401 sb.append("id=").append(id).append(", "); 402 } 403 404 sb.append("startX=").append(getStartX()); 405 sb.append(", startY=").append(getStartY()); 406 sb.append(", controlX=").append(getControlX()); 407 sb.append(", controlY=").append(getControlY()); 408 sb.append(", endX=").append(getEndX()); 409 sb.append(", endY=").append(getEndY()); 410 411 sb.append(", fill=").append(getFill()); 412 413 Paint stroke = getStroke(); 414 if (stroke != null) { 415 sb.append(", stroke=").append(stroke); 416 sb.append(", strokeWidth=").append(getStrokeWidth()); 417 } 418 419 return sb.append("]").toString(); 420 } 421 } 422