下面列出了怎么用javafx.scene.shape.Path的API类实例代码及写法,或者点击链接到github查看源代码。
protected void displaySelection() {
logger.finest(" - DisplaySelection - Try to print " + dragstartindex + " - " + dragendindex);
if (this.dragstartindex >= 0)
if (this.dragendindex >= 0)
if (this.dragendindex > this.dragstartindex) {
hideSelection();
TextLayout textlayout = (TextLayout) invoke(getTextLayout, textflow);
PathElement[] highlight = textlayout.getRange(this.dragstartindex, this.dragendindex,
TextLayout.TYPE_TEXT, 0, 0);
hightlightpath = new Path(highlight);
hightlightpath.setManaged(false);
hightlightpath.setFill(Color.web("#222235", 0.2));
hightlightpath.setStrokeWidth(0);
if (title)
hightlightpath.setTranslateY(6);
if (bulletpoint) {
hightlightpath.setTranslateY(2);
hightlightpath.setTranslateX(5);
}
textflow.getChildren().add(hightlightpath);
textflow.requestLayout();
textflow.requestFocus();
}
}
@Override
public void draw(Edge pEdge, GraphicsContext pGraphics)
{
ToolGraphics.strokeSharpPath(pGraphics, (Path) getShape(pEdge), LineStyle.SOLID);
Line connectionPoints = getConnectionPoints(pEdge);
if(isSShaped(pEdge))
{
ArrowHead.BLACK_TRIANGLE.view().draw(pGraphics,
new Point(connectionPoints.getX2() - ENDSIZE, connectionPoints.getY2()),
new Point(connectionPoints.getX2(), connectionPoints.getY2()));
}
else
{
ArrowHead.BLACK_TRIANGLE.view().draw(pGraphics,
new Point(connectionPoints.getX2() + ENDSIZE, connectionPoints.getY2()),
new Point(connectionPoints.getX2(), connectionPoints.getY2()));
}
}
private Path getCShape(Line pConnectionPoints)
{
final int x1 = Math.max(pConnectionPoints.getX1(), pConnectionPoints.getX2()) + ENDSIZE;
final int y1 = pConnectionPoints.getY1();
final int x2 = x1 + ENDSIZE;
final int y2 = pConnectionPoints.getY2();
final int ymid = (pConnectionPoints.getY1() + pConnectionPoints.getY2()) / 2;
MoveTo moveTo = new MoveTo(pConnectionPoints.getX1(), y1);
LineTo lineTo1 = new LineTo(x1, y1);
QuadCurveTo quadTo1 = new QuadCurveTo(x2, y1, x2, ymid);
QuadCurveTo quadTo2 = new QuadCurveTo(x2, y2, x1, y2);
LineTo lineTo2 = new LineTo(pConnectionPoints.getX2(), y2);
Path path = new Path();
path.getElements().addAll(moveTo, lineTo1, quadTo1, quadTo2, lineTo2);
return path;
}
private Path getSShape(Line pConnectionPoints)
{
final int x1 = pConnectionPoints.getX1() + ENDSIZE;
final int y1 = pConnectionPoints.getY1();
final int x2 = pConnectionPoints.getX2() - ENDSIZE;
final int y2 = pConnectionPoints.getY2();
final int xmid = (pConnectionPoints.getX1() + pConnectionPoints.getX2()) / 2;
final int ymid = (pConnectionPoints.getY1() + pConnectionPoints.getY2()) / 2;
MoveTo moveTo = new MoveTo(pConnectionPoints.getX1(), y1);
LineTo lineTo1 = new LineTo(x1, y1);
QuadCurveTo quadTo1 = new QuadCurveTo((x1 + xmid) / 2, y1, xmid, ymid);
QuadCurveTo quadTo2 = new QuadCurveTo((x2 + xmid) / 2, y2, x2, y2);
LineTo lineTo2 = new LineTo(pConnectionPoints.getX2(), y2);
Path path = new Path();
path.getElements().addAll(moveTo, lineTo1, quadTo1, quadTo2, lineTo2);
return path;
}
protected void shake(int i1, int j1) {
try {
VBox vbox = chessBoard.get(i1 + "-" + j1);
double x = vbox.getLayoutX();
double y = vbox.getLayoutY();
Path path = new Path();
path.getElements().add(new LineTo(x - 20, y + 18));
path.getElements().add(new LineTo(x + 20, y + 18));
path.getElements().add(new LineTo(x - 20, y + 18));
path.getElements().add(new LineTo(x + 20, y + 18));
path.getElements().add(new LineTo(x, y));
PathTransition pathTransition = new PathTransition(Duration.millis(200), path, vbox);
pathTransition.setCycleCount(3);
pathTransition.setAutoReverse(true);
pathTransition.play();
} catch (Exception e) {
logger.debug(e.toString());
}
}
@Override protected void seriesAdded(Series<Number, Number> series, int seriesIndex) {
// handle any data already in series
for (int j = 0; j < series.getData().size(); j++) {
Data item = series.getData().get(j);
Node candle = createCandle(seriesIndex, item, j);
if (shouldAnimate()) {
candle.setOpacity(0);
getPlotChildren().add(candle);
// fade in new candle
FadeTransition ft = new FadeTransition(Duration.millis(500), candle);
ft.setToValue(1);
ft.play();
} else {
getPlotChildren().add(candle);
}
}
// create series path
Path seriesPath = new Path();
seriesPath.getStyleClass().setAll("candlestick-average-line", "series" + seriesIndex);
series.setNode(seriesPath);
getPlotChildren().add(seriesPath);
}
@Override protected void seriesAdded(Series<Number, Number> series, int seriesIndex) {
// handle any data already in series
for (int j = 0; j < series.getData().size(); j++) {
Data item = series.getData().get(j);
Node candle = createCandle(seriesIndex, item, j);
if (shouldAnimate()) {
candle.setOpacity(0);
getPlotChildren().add(candle);
// fade in new candle
FadeTransition ft = new FadeTransition(Duration.millis(500), candle);
ft.setToValue(1);
ft.play();
} else {
getPlotChildren().add(candle);
}
}
// create series path
Path seriesPath = new Path();
seriesPath.getStyleClass().setAll("candlestick-average-line", "series" + seriesIndex);
series.setNode(seriesPath);
getPlotChildren().add(seriesPath);
}
/**
* Adjusts the curveClip so that the curve node does not paint through the
* given decoration.
*
* @param curveShape
* A shape describing the {@link ICurve} geometry, which is used
* for clipping.
*
* @param curveClip
* A shape that represents the clip of the curve node,
* interpreted in scene coordinates.
* @param decoration
* The decoration to clip the curve node from.
* @return A shape representing the resulting clip, interpreted in scene
* coordinates.
*/
protected Shape clipAtDecoration(Shape curveShape, Shape curveClip,
Shape decoration) {
// first intersect curve shape with decoration layout bounds,
// then subtract the curve shape from the result, and the decoration
// from that
Path decorationShapeBounds = new Path(
Geometry2Shape.toPathElements(NodeUtils
.localToScene(decoration,
NodeUtils.getShapeBounds(decoration))
.toPath()));
decorationShapeBounds.setFill(Color.RED);
Shape clip = Shape.intersect(decorationShapeBounds, curveShape);
clip = Shape.subtract(clip, decoration);
clip = Shape.subtract(curveClip, clip);
return clip;
}
public Bounds getRangeBoundsOnScreen(int from, int to) {
layout(); // ensure layout, is a no-op if not dirty
PathElement[] rangeShape = getRangeShapeSafely(from, to);
Path p = new Path();
p.setManaged(false);
p.setLayoutX(getInsets().getLeft());
p.setLayoutY(getInsets().getTop());
getChildren().add(p);
p.getElements().setAll(rangeShape);
Bounds localBounds = p.getBoundsInLocal();
Bounds rangeBoundsOnScreen = p.localToScreen(localBounds);
getChildren().remove(p);
return rangeBoundsOnScreen;
}
private Shape getShape(double zoomLevel, boolean effectsOn) {
segment.setWidth(organ.getLength() + getOverlap() * 2);
segment.setHeight(organ.getThickness());
segment.getTransforms().clear();
// overlap slightly and shift to center based on thickness
double widthCenter = organ.getThickness() / 2;
segment.getTransforms().add(moveToStartPoint());
segment.getTransforms().add(new Translate(-getOverlap(), -widthCenter));
segment.getTransforms().add(new Rotate(organ.getAbsoluteAngle(), getOverlap(), widthCenter));
boolean isHighDetail = hasJoint && zoomLevel >= VERY_HIGH_MAGNIFICATION && effectsOn;
if (!isHighDetail)
return segment;
joint.setRadius(getJointRadius(organ.getThickness()));
joint.getTransforms().clear();
joint.getTransforms().add(moveToStartPoint());
joint.getTransforms().add(new Translate(organ.getLength(), 0));
joint.getTransforms().add(new Rotate(organ.getAbsoluteAngle(), -organ.getLength(), 0));
return Path.union(segment, joint);
}
private void initGraphics() {
if (Double.compare(getPrefWidth(), 0.0) <= 0 || Double.compare(getPrefHeight(), 0.0) <= 0 || Double.compare(getWidth(), 0.0) <= 0 ||
Double.compare(getHeight(), 0.0) <= 0) {
if (getPrefWidth() > 0 && getPrefHeight() > 0) {
setPrefSize(getPrefWidth(), getPrefHeight());
} else {
setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
}
path = new Path();
path.setStroke(Color.TRANSPARENT);
icon = new Path();
icon.setStroke(Color.TRANSPARENT);
tooltip = new Tooltip("");
getChildren().setAll(path, icon);
}
private void initGraphics() {
if (Double.compare(getPrefWidth(), 0.0) <= 0 || Double.compare(getPrefHeight(), 0.0) <= 0 || Double.compare(getWidth(), 0.0) <= 0 ||
Double.compare(getHeight(), 0.0) <= 0) {
if (getPrefWidth() > 0 && getPrefHeight() > 0) {
setPrefSize(getPrefWidth(), getPrefHeight());
} else {
setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
}
path = new Path();
path.setStroke(Color.TRANSPARENT);
icon = new Path();
icon.setStroke(Color.TRANSPARENT);
tooltip = new Tooltip("");
getChildren().setAll(path, icon);
}
public Text3DHelper(String text, String font, int size){
this.text=text;
list=new ArrayList<>();
Text textNode = new Text(text);
textNode.setFont(new Font(font,size));
// Convert Text to Path
Path subtract = (Path)(Shape.subtract(textNode, new Rectangle(0, 0)));
// Convert Path elements into lists of points defining the perimeter (exterior or interior)
subtract.getElements().forEach(this::getPoints);
// Group exterior polygons with their interior polygons
polis.stream().filter(LineSegment::isHole).forEach(hole->{
polis.stream().filter(poly->!poly.isHole())
.filter(poly->!((Path)Shape.intersect(poly.getPath(), hole.getPath())).getElements().isEmpty())
.filter(poly->poly.getPath().contains(new Point2D(hole.getOrigen().x,hole.getOrigen().y)))
.forEach(poly->poly.addHole(hole));
});
polis.removeIf(LineSegment::isHole);
}
private static Path processPath(final List<String> PATH_LIST, final PathReader READER) {
final Path PATH = new Path();
PATH.setFillRule(FillRule.EVEN_ODD);
while (!PATH_LIST.isEmpty()) {
if ("M".equals(READER.read())) {
PATH.getElements().add(new MoveTo(READER.nextX(), READER.nextY()));
} else if ("L".equals(READER.read())) {
PATH.getElements().add(new LineTo(READER.nextX(), READER.nextY()));
} else if ("C".equals(READER.read())) {
PATH.getElements().add(new CubicCurveTo(READER.nextX(), READER.nextY(), READER.nextX(), READER.nextY(), READER.nextX(), READER.nextY()));
} else if ("Q".equals(READER.read())) {
PATH.getElements().add(new QuadCurveTo(READER.nextX(), READER.nextY(), READER.nextX(), READER.nextY()));
} else if ("H".equals(READER.read())) {
PATH.getElements().add(new HLineTo(READER.nextX()));
} else if ("L".equals(READER.read())) {
PATH.getElements().add(new VLineTo(READER.nextY()));
} else if ("A".equals(READER.read())) {
PATH.getElements().add(new ArcTo(READER.nextX(), READER.nextY(), 0, READER.nextX(), READER.nextY(), false, false));
} else if ("Z".equals(READER.read())) {
PATH.getElements().add(new ClosePath());
}
}
return PATH;
}
/**
* Strokes and fills a path, by converting the elements to integer coordinates and then
* aligning them to the center of the pixels, so that it aligns precisely
* with the JavaFX coordinate system. See the documentation for
* javafx.scene.shape.Shape for details.
*
* @param pGraphics The graphics context.
* @param pPath The path to stroke
* @param pFill The fill color for the path.
* @param pShadow True to include a drop shadow.
*/
public static void strokeAndFillSharpPath(GraphicsContext pGraphics, Path pPath, Paint pFill, boolean pShadow)
{
double width = pGraphics.getLineWidth();
Paint fill = pGraphics.getFill();
pGraphics.setLineWidth(LINE_WIDTH);
pGraphics.setFill(pFill);
applyPath(pGraphics, pPath);
if( pShadow )
{
pGraphics.setEffect(DROP_SHADOW);
}
pGraphics.fill();
pGraphics.stroke();
pGraphics.setLineWidth(width);
pGraphics.setFill(fill);
pGraphics.setEffect(null);
}
@Override
protected Shape getShape(Edge pEdge)
{
Point[] points = getPoints(pEdge);
Path path = new Path();
Point point = points[points.length - 1];
MoveTo moveTo = new MoveTo(point.getX(), point.getY());
path.getElements().add(moveTo);
for(int i = points.length - 2; i >= 0; i--)
{
point = points[i];
LineTo lineTo = new LineTo(point.getX(), point.getY());
path.getElements().add(lineTo);
}
return path;
}
@Override
protected void dataItemRemoved(XYChart.Data<Number, Number> item, XYChart.Series<Number, Number> series) {
if (series.getNode() instanceof Path) {
Path seriesPath = (Path) series.getNode();
seriesPath.getElements().clear();
}
final Node node = item.getNode();
if (shouldAnimate()) {
// fade out old candle
FadeTransition ft = new FadeTransition(Duration.millis(500), node);
ft.setToValue(0);
ft.setOnFinished((ActionEvent actionEvent) -> {
getPlotChildren().remove(node);
removeDataItemFromDisplay(series, item);
});
ft.play();
} else {
getPlotChildren().remove(node);
removeDataItemFromDisplay(series, item);
}
}
@Test
void testOnChangeDotStyle() {
model.setPlotStyle(PlotStyle.DOTS);
WaitForAsyncUtils.waitForFxEvents();
final List<PathElement> before = ((Path) ((ViewDot) view.getChildren().get(0)).getChildren().get(1)).getElements();
model.setDotStyle(DotStyle.FDIAMOND);
WaitForAsyncUtils.waitForFxEvents();
assertNotEquals(before, ((Path) ((ViewDot) view.getChildren().get(0)).getChildren().get(1)).getElements());
}
private ObjectTag addObjectTag(String label, ShapeItem.Type type, Path path) {
var bounds = path.getBoundsInLocal();
ObjectModel om = new ObjectModel(label, bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY());
if (type == POLYGON) {
om.setPolygon(AppUtils.getPolygonPoints(path));
}
return addObjectTag(om, bundle.getString("menu.create"));
}
@Override
public Canvas createIcon(Edge pEdge)
{
final float scale = 0.6f;
final int offset = 25;
Canvas canvas = new Canvas(BUTTON_SIZE, BUTTON_SIZE);
GraphicsContext graphics = canvas.getGraphicsContext2D();
canvas.getGraphicsContext2D().scale(scale, scale);
Path path = new Path();
path.getElements().addAll(new MoveTo(1, offset), new LineTo(BUTTON_SIZE*(1/scale)-1, offset));
ToolGraphics.strokeSharpPath(graphics, path, LineStyle.DOTTED);
ArrowHead.V.view().draw(graphics, new Point((int)(BUTTON_SIZE*(1/scale)-1), offset), new Point(1, offset));
return canvas;
}
public ShapeChartArea(ChartSerie serie) {
pFill = new Path();
pFill.getStyleClass().add(serie.getStyleClass() + "-fill");
pFill.setStrokeWidth(0.0);
pLine = new Path();
pLine.getStyleClass().add(serie.getStyleClass() + "-line");
this.serie = serie;
serie.setListener(this);
}
private void initGraphics() {
if (Double.compare(getPrefWidth(), 0.0) <= 0 || Double.compare(getPrefHeight(), 0.0) <= 0
|| Double.compare(getWidth(), 0.0) <= 0 || Double.compare(getHeight(), 0.0) <= 0) {
if (getPrefWidth() > 0 && getPrefHeight() > 0) {
setPrefSize(getPrefWidth(), getPrefHeight());
} else {
setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT); // 11x7
}
}
state = State.CONSTANT;
triangle = new Path();
triangle.setStroke(null);
triangle.setFill(state.color);
triangle.setRotate(state.angle);
nameText = new Text(getName());
nameText.setTextOrigin(VPos.TOP);
valueText = new Text(String.format(locale, formatString, getValue()));
valueText.setTextOrigin(VPos.TOP);
separator = new Line();
pane = new Pane(triangle, nameText, valueText, separator);
pane.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)));
getChildren().setAll(pane);
}
public void setSeriesColor(final XYChart.Series<X, Y> SERIES, final Paint STROKE, final Paint FILL, final Background SYMBOL_BACKGROUND, final Paint LEGEND_SYMBOL_FILL) {
if (getData().isEmpty()) { return; }
if (!getData().contains(SERIES)) { return; }
if (null != FILL) { ((Path) ((Group) SERIES.getNode()).getChildren().get(0)).setFill(FILL); }
if (null != STROKE) { ((Path) ((Group) SERIES.getNode()).getChildren().get(1)).setStroke(STROKE); }
if (null != SYMBOL_BACKGROUND) { setSymbolFill(SERIES, SYMBOL_BACKGROUND); }
}
public static Path svgPathToPath(final SVGPath SVG_PATH) {
String data = SVG_PATH.getContent();
data = data.replaceAll("/(,)/", "/ /");
data = data.replaceAll("/([A-Za-z])/", "/ $1 /"); // wrap single characters in blanks
StringTokenizer tokenizer = new StringTokenizer(data, " ");
List<String> pathList = new ArrayList<>();
while(tokenizer.hasMoreElements()) {
pathList.add(tokenizer.nextElement().toString());
}
PathReader pathReader = new PathReader(pathList);
return processPath(pathList, pathReader);
}
private Path getSegmentPath(Edge pEdge)
{
Point2D[] points = getPoints(pEdge);
Path path = new Path();
Point2D p = points[points.length - 1];
MoveTo moveTo = new MoveTo((float) p.getX(), (float) p.getY());
path.getElements().add(moveTo);
for(int i = points.length - 2; i >= 0; i--)
{
p = points[i];
LineTo lineTo = new LineTo((float) p.getX(), (float) p.getY());
path.getElements().add(lineTo);
}
return path;
}
/**
* Converts a JFX path to an SVGPath.
* @param path To JFX path to convert.
* @param doc The SVG document.
* @return The created SVGPath.
* @throws NullPointerException If one of the given parameter is null.
*/
public SVGPathElement pathToSVGPath(final Path path, final SVGDocument doc) {
final SVGPathElement svgPath = new SVGPathElement(doc);
final SVGPathSegList list = new SVGPathSegList();
list.addAll(path.getElements().stream().map(elt -> createSVGPathSeg(elt)).filter(elt -> elt != null).collect(Collectors.toList()));
svgPath.setPathData(list);
copyPropertiesToSVG(svgPath, path);
return svgPath;
}
/**
* Node that represents the playing area/desktop where the puzzle pieces sit
*/
Desk(int numOfColumns, int numOfRows) {
setStyle("-fx-background-color: #cccccc; "
+ "-fx-border-color: #464646; "
+ "-fx-effect: innershadow( two-pass-box , rgba(0,0,0,0.8) , 15, 0.0 , 0 , 4 );");
double DESK_WIDTH = Piece.SIZE * numOfColumns;
double DESK_HEIGHT = Piece.SIZE * numOfRows;
setPrefSize(DESK_WIDTH, DESK_HEIGHT);
setMaxSize(DESK_WIDTH, DESK_HEIGHT);
autosize();
// create path for lines
Path grid = new Path();
grid.setStroke(Color.rgb(70, 70, 70));
getChildren().add(grid);
// create vertical lines
for (int col = 0; col < numOfColumns - 1; col++) {
grid.getElements().addAll(
new MoveTo(Piece.SIZE + Piece.SIZE * col, 5),
new LineTo(Piece.SIZE + Piece.SIZE * col, Piece.SIZE * numOfRows - 5));
}
// create horizontal lines
for (int row = 0; row < numOfRows - 1; row++) {
grid.getElements().addAll(
new MoveTo(5, Piece.SIZE + Piece.SIZE * row),
new LineTo(Piece.SIZE * numOfColumns - 5, Piece.SIZE + Piece.SIZE * row));
}
}
@Deprecated
public static Node create(final Consumer<Path> pathSetup, final double size)
{
final StackPane closeBtn = new StackPane();
final Path path = new Path();
pathSetup.accept(path);
path.getElements().addAll(
new MoveTo(0, 0),
new LineTo(size, size),
new MoveTo(0, size),
new LineTo(size, 0)
);
closeBtn.getChildren().add(path);
return closeBtn;
}
public PathSample() {
super(180,90);
// Create path shape - square
Path path1 = new Path();
path1.getElements().addAll(
new MoveTo(25, 25),
new HLineTo(65),
new VLineTo(65),
new LineTo(25, 65),
new ClosePath()
);
path1.setFill(null);
path1.setStroke(Color.RED);
path1.setStrokeWidth(2);
// Create path shape - curves
Path path2 = new Path();
path2.getElements().addAll(
new MoveTo(100, 45),
new CubicCurveTo(120, 20, 130, 80, 140, 45),
new QuadCurveTo(150, 0, 160, 45),
new ArcTo(20, 40, 0, 180, 45, true, true)
);
path2.setFill(null);
path2.setStroke(Color.DODGERBLUE);
path2.setStrokeWidth(2);
// show the path shapes;
getChildren().add(new Group(path1, path2));
// REMOVE ME
setControls(
new SimplePropertySheet.PropDesc("Path 1 Stroke", path1.strokeProperty()),
new SimplePropertySheet.PropDesc("Path 2 Stroke", path2.strokeProperty())
);
// END REMOVE ME
}
/**
* Strokes a path, by converting the elements to integer coordinates and then
* aligning them to the center of the pixels, so that it aligns precisely
* with the JavaFX coordinate system. See the documentation for
* javafx.scene.shape.Shape for details.
*
* @param pGraphics The graphics context.
* @param pPath The path to stroke
* @param pStyle The line style for the path.
*/
public static void strokeSharpPath(GraphicsContext pGraphics, Path pPath, LineStyle pStyle)
{
double[] oldDash = pGraphics.getLineDashes();
pGraphics.setLineDashes(pStyle.getLineDashes());
double width = pGraphics.getLineWidth();
pGraphics.setLineWidth(LINE_WIDTH);
applyPath(pGraphics, pPath);
pGraphics.stroke();
pGraphics.setLineDashes(oldDash);
pGraphics.setLineWidth(width);
}