< prev index next >

modules/graphics/src/main/java/javafx/scene/shape/Path.java

Print this page




  88 path.getElements().add(lineTo);
  89 path.getElements().add(arcTo);
  90 
  91 </PRE>
  92  * @since JavaFX 2.0
  93  */
  94 public class Path extends Shape {
  95     static {
  96         PathHelper.setPathAccessor(new PathHelper.PathAccessor() {
  97             @Override
  98             public NGNode doCreatePeer(Node node) {
  99                 return ((Path) node).doCreatePeer();
 100             }
 101 
 102             @Override
 103             public void doUpdatePeer(Node node) {
 104                 ((Path) node).doUpdatePeer();
 105             }
 106 
 107             @Override





 108             public Paint doCssGetFillInitialValue(Shape shape) {
 109                 return ((Path) shape).doCssGetFillInitialValue();
 110             }
 111 
 112             @Override
 113             public Paint doCssGetStrokeInitialValue(Shape shape) {
 114                 return ((Path) shape).doCssGetStrokeInitialValue();
 115             }
 116 
 117             @Override
 118             public com.sun.javafx.geom.Shape doConfigShape(Shape shape) {
 119                 return ((Path) shape).doConfigShape();
 120             }
 121 
 122         });
 123     }
 124 
 125     private Path2D path2d = null;
 126 
 127     {


 149     public Path(PathElement... elements) {
 150         if (elements != null) {
 151             this.elements.addAll(elements);
 152         }
 153     }
 154 
 155     /**
 156      * Creates new instance of Path
 157      * @param elements The collection of the elements of the Path
 158      * @since JavaFX 2.2
 159      */
 160     public Path(Collection<? extends PathElement> elements) {
 161         if (elements != null) {
 162             this.elements.addAll(elements);
 163         }
 164     }
 165 
 166     void markPathDirty() {
 167         path2d = null;
 168         NodeHelper.markDirty(this, DirtyBits.NODE_CONTENTS);
 169         impl_geomChanged();
 170     }
 171 
 172     /**
 173      * Defines the filling rule constant for determining the interior of the path.
 174      * The value must be one of the following constants:
 175      * {@code FillRile.EVEN_ODD} or {@code FillRule.NON_ZERO}.
 176      * The default value is {@code FillRule.NON_ZERO}.
 177      *
 178      * @defaultValue FillRule.NON_ZERO
 179      */
 180     private ObjectProperty<FillRule> fillRule;
 181 
 182     public final void setFillRule(FillRule value) {
 183         if (fillRule != null || value != FillRule.NON_ZERO) {
 184             fillRuleProperty().set(value);
 185         }
 186     }
 187 
 188     public final FillRule getFillRule() {
 189         return fillRule == null ? FillRule.NON_ZERO : fillRule.get();
 190     }
 191 
 192     public final ObjectProperty<FillRule> fillRuleProperty() {
 193         if (fillRule == null) {
 194             fillRule = new ObjectPropertyBase<FillRule>(FillRule.NON_ZERO) {
 195 
 196                 @Override
 197                 public void invalidated() {
 198                     NodeHelper.markDirty(Path.this, DirtyBits.NODE_CONTENTS);
 199                     impl_geomChanged();
 200                 }
 201 
 202                 @Override
 203                 public Object getBean() {
 204                     return Path.this;
 205                 }
 206 
 207                 @Override
 208                 public String getName() {
 209                     return "fillRule";
 210                 }
 211             };
 212         }
 213         return fillRule;
 214     }
 215 
 216     private boolean isPathValid;
 217     /**
 218      * Defines the array of path elements of this path.
 219      *


 239             // we cannot count the number of PathElements removed (fast enough).
 240             // Thus we can optimize only if some elements were added to the end
 241             if (path2d != null) {
 242                 c.reset();
 243                 c.next();
 244                 // we just have to check the first change, as more changes cannot come after such change
 245                 if (c.getFrom() == c.getList().size() && !c.wasRemoved() && c.wasAdded()) {
 246                     // some elements added
 247                     for (int i = c.getFrom(); i < c.getTo(); ++i) {
 248                         PathElementHelper.addTo(list.get(i), path2d);
 249                     }
 250                 } else {
 251                     path2d = null;
 252                 }
 253             }
 254             if (firstElementChanged) {
 255                 isPathValid = isFirstPathElementValid();
 256             }
 257 
 258             NodeHelper.markDirty(Path.this, DirtyBits.NODE_CONTENTS);
 259             impl_geomChanged();
 260         }
 261     };
 262 
 263     /**
 264      * Gets observable list of path elements of this path.
 265      * @return Elements of this path
 266      */
 267     public final ObservableList<PathElement> getElements() { return elements; }
 268 
 269     /*
 270      * Note: This method MUST only be called via its accessor method.
 271      */
 272     private NGNode doCreatePeer() {
 273         return new NGPath();
 274     }
 275 
 276     /*
 277      * Note: This method MUST only be called via its accessor method.
 278      */
 279     private Path2D doConfigShape() {
 280         if (isPathValid) {
 281             if (path2d == null) {
 282                 path2d = PathUtils.configShape(getElements(), getFillRule() == FillRule.EVEN_ODD);
 283             } else {
 284                 path2d.setWindingRule(getFillRule() == FillRule.NON_ZERO ?
 285                                       Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD);
 286             }
 287             return path2d;
 288         } else {
 289             return new Path2D();
 290         }
 291     }
 292 
 293     /**
 294      * @treatAsPrivate implementation detail
 295      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 296      */
 297     @Deprecated
 298     @Override
 299     protected Bounds impl_computeLayoutBounds() {
 300        if (isPathValid) {
 301            return super.impl_computeLayoutBounds();
 302        }
 303        return new BoundingBox(0, 0, -1, -1); //create empty bounds
 304     }
 305 
 306     private boolean isFirstPathElementValid() {
 307         ObservableList<PathElement> _elements = getElements();
 308         if (_elements != null && _elements.size() > 0) {
 309             PathElement firstElement = _elements.get(0);
 310             if (!firstElement.isAbsolute()) {
 311                 System.err.printf("First element of the path can not be relative. Path: %s\n", this);
 312                 return false;
 313             } else if (firstElement instanceof MoveTo) {
 314                 return true;
 315             } else {
 316                 System.err.printf("Missing initial moveto in path definition. Path: %s\n", this);
 317                 return false;
 318             }
 319         }
 320         return true;
 321     }




  88 path.getElements().add(lineTo);
  89 path.getElements().add(arcTo);
  90 
  91 </PRE>
  92  * @since JavaFX 2.0
  93  */
  94 public class Path extends Shape {
  95     static {
  96         PathHelper.setPathAccessor(new PathHelper.PathAccessor() {
  97             @Override
  98             public NGNode doCreatePeer(Node node) {
  99                 return ((Path) node).doCreatePeer();
 100             }
 101 
 102             @Override
 103             public void doUpdatePeer(Node node) {
 104                 ((Path) node).doUpdatePeer();
 105             }
 106 
 107             @Override
 108             public Bounds doComputeLayoutBounds(Node node) {
 109                 return ((Path) node).doComputeLayoutBounds();
 110             }
 111 
 112             @Override
 113             public Paint doCssGetFillInitialValue(Shape shape) {
 114                 return ((Path) shape).doCssGetFillInitialValue();
 115             }
 116 
 117             @Override
 118             public Paint doCssGetStrokeInitialValue(Shape shape) {
 119                 return ((Path) shape).doCssGetStrokeInitialValue();
 120             }
 121 
 122             @Override
 123             public com.sun.javafx.geom.Shape doConfigShape(Shape shape) {
 124                 return ((Path) shape).doConfigShape();
 125             }
 126 
 127         });
 128     }
 129 
 130     private Path2D path2d = null;
 131 
 132     {


 154     public Path(PathElement... elements) {
 155         if (elements != null) {
 156             this.elements.addAll(elements);
 157         }
 158     }
 159 
 160     /**
 161      * Creates new instance of Path
 162      * @param elements The collection of the elements of the Path
 163      * @since JavaFX 2.2
 164      */
 165     public Path(Collection<? extends PathElement> elements) {
 166         if (elements != null) {
 167             this.elements.addAll(elements);
 168         }
 169     }
 170 
 171     void markPathDirty() {
 172         path2d = null;
 173         NodeHelper.markDirty(this, DirtyBits.NODE_CONTENTS);
 174         NodeHelper.geomChanged(this);
 175     }
 176 
 177     /**
 178      * Defines the filling rule constant for determining the interior of the path.
 179      * The value must be one of the following constants:
 180      * {@code FillRile.EVEN_ODD} or {@code FillRule.NON_ZERO}.
 181      * The default value is {@code FillRule.NON_ZERO}.
 182      *
 183      * @defaultValue FillRule.NON_ZERO
 184      */
 185     private ObjectProperty<FillRule> fillRule;
 186 
 187     public final void setFillRule(FillRule value) {
 188         if (fillRule != null || value != FillRule.NON_ZERO) {
 189             fillRuleProperty().set(value);
 190         }
 191     }
 192 
 193     public final FillRule getFillRule() {
 194         return fillRule == null ? FillRule.NON_ZERO : fillRule.get();
 195     }
 196 
 197     public final ObjectProperty<FillRule> fillRuleProperty() {
 198         if (fillRule == null) {
 199             fillRule = new ObjectPropertyBase<FillRule>(FillRule.NON_ZERO) {
 200 
 201                 @Override
 202                 public void invalidated() {
 203                     NodeHelper.markDirty(Path.this, DirtyBits.NODE_CONTENTS);
 204                     NodeHelper.geomChanged(Path.this);
 205                 }
 206 
 207                 @Override
 208                 public Object getBean() {
 209                     return Path.this;
 210                 }
 211 
 212                 @Override
 213                 public String getName() {
 214                     return "fillRule";
 215                 }
 216             };
 217         }
 218         return fillRule;
 219     }
 220 
 221     private boolean isPathValid;
 222     /**
 223      * Defines the array of path elements of this path.
 224      *


 244             // we cannot count the number of PathElements removed (fast enough).
 245             // Thus we can optimize only if some elements were added to the end
 246             if (path2d != null) {
 247                 c.reset();
 248                 c.next();
 249                 // we just have to check the first change, as more changes cannot come after such change
 250                 if (c.getFrom() == c.getList().size() && !c.wasRemoved() && c.wasAdded()) {
 251                     // some elements added
 252                     for (int i = c.getFrom(); i < c.getTo(); ++i) {
 253                         PathElementHelper.addTo(list.get(i), path2d);
 254                     }
 255                 } else {
 256                     path2d = null;
 257                 }
 258             }
 259             if (firstElementChanged) {
 260                 isPathValid = isFirstPathElementValid();
 261             }
 262 
 263             NodeHelper.markDirty(Path.this, DirtyBits.NODE_CONTENTS);
 264             NodeHelper.geomChanged(Path.this);
 265         }
 266     };
 267 
 268     /**
 269      * Gets observable list of path elements of this path.
 270      * @return Elements of this path
 271      */
 272     public final ObservableList<PathElement> getElements() { return elements; }
 273 
 274     /*
 275      * Note: This method MUST only be called via its accessor method.
 276      */
 277     private NGNode doCreatePeer() {
 278         return new NGPath();
 279     }
 280 
 281     /*
 282      * Note: This method MUST only be called via its accessor method.
 283      */
 284     private Path2D doConfigShape() {
 285         if (isPathValid) {
 286             if (path2d == null) {
 287                 path2d = PathUtils.configShape(getElements(), getFillRule() == FillRule.EVEN_ODD);
 288             } else {
 289                 path2d.setWindingRule(getFillRule() == FillRule.NON_ZERO ?
 290                                       Path2D.WIND_NON_ZERO : Path2D.WIND_EVEN_ODD);
 291             }
 292             return path2d;
 293         } else {
 294             return new Path2D();
 295         }
 296     }
 297 
 298     private Bounds doComputeLayoutBounds() {






 299        if (isPathValid) {
 300            return null; // Helper will need to call its super's compute layout bounds
 301        }
 302        return new BoundingBox(0, 0, -1, -1); //create empty bounds
 303     }
 304 
 305     private boolean isFirstPathElementValid() {
 306         ObservableList<PathElement> _elements = getElements();
 307         if (_elements != null && _elements.size() > 0) {
 308             PathElement firstElement = _elements.get(0);
 309             if (!firstElement.isAbsolute()) {
 310                 System.err.printf("First element of the path can not be relative. Path: %s\n", this);
 311                 return false;
 312             } else if (firstElement instanceof MoveTo) {
 313                 return true;
 314             } else {
 315                 System.err.printf("Missing initial moveto in path definition. Path: %s\n", this);
 316                 return false;
 317             }
 318         }
 319         return true;
 320     }


< prev index next >