下面列出了怎么用javafx.scene.shape.Shape的API类实例代码及写法,或者点击链接到github查看源代码。
@Override protected void updateDetail(final String propertyName) {
final boolean all = propertyName.equals("*") ? true : false;
final Shape shapeNode = (Shape) getTarget();
if (all || propertyName.equals("fill")) {
if (shapeNode != null && shapeNode.getFill() == null) {
Logger.print("Error: null shape fill for property " + propertyName);
}
fillDetail.setValue(shapeNode != null && shapeNode.getFill() != null ? shapeNode.getFill().toString() : "-");
fillDetail.setIsDefault(shapeNode == null || shapeNode.getFill() == null);
fillDetail.setSimpleProperty((shapeNode != null) ? shapeNode.fillProperty() : null);
if (!all)
fillDetail.updated();
if (!all)
return;
}
if (all)
sendAllDetails();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
switch (qName) {
case "polygon":
final double[] points = new double[polygonPoints.size()];
for (int i = 0; i < polygonPoints.size(); i++)
points[i] = polygonPoints.get(i);
currentRegion = new PolygonRegion(points);
((Shape) currentRegion).setFill(polygonFill);
case "image":
case "rectangle":
case "ellipse":
currentRegion.setTags(currentTags);
regions.add((Node) currentRegion);
break;
}
}
@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;
}
private void registerListeners() {
widthProperty().addListener(o -> resize());
heightProperty().addListener(o -> resize());
sceneProperty().addListener(o -> {
if (!locations.isEmpty()) { addShapesToScene(locations.values()); }
if (isZoomEnabled()) { getScene().addEventFilter( ScrollEvent.ANY, new WeakEventHandler<>(_scrollEventHandler)); }
locations.addListener((MapChangeListener<Location, Shape>) CHANGE -> {
if (CHANGE.wasAdded()) {
addShapesToScene(CHANGE.getValueAdded());
} else if(CHANGE.wasRemoved()) {
Platform.runLater(() -> pane.getChildren().remove(CHANGE.getValueRemoved()));
}
});
});
}
@FXML
public void startPolygon(ActionEvent event) {
if (cursorRegion.isPresent() && targetRegions.contains(cursorRegion.get())) {
final TargetRegion selected = (TargetRegion) cursorRegion.get();
if (selected.getType() != RegionType.IMAGE)
((Shape) selected).setStroke(TargetRegion.UNSELECTED_STROKE_COLOR);
if (tagsButton.isSelected()) {
tagsButton.setSelected(false);
toggleTagEditor();
}
toggleShapeControls(false);
}
clearFreeformState(false);
}
@Override
public Node toNode(double zoomLevel, boolean infraredOn, boolean effectsOn) {
if (organ.isAtrophic())
return null;
double alpha = getAlpha(zoomLevel);
if (alpha == 0)
return null; // perfectly transparent. don't draw.
Shape shape = getShape(zoomLevel, effectsOn);
addFill(shape, infraredOn, alpha);
addStroke(shape, infraredOn, alpha, zoomLevel);
addMotionBlurEffect(shape, zoomLevel, effectsOn);
previousOrganPosition = organ.toSegment();
return shape;
}
/**
* 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;
}
private void refreshShape() {
Node shape = ZestProperties.getShape(getContent());
if (this.shape != shape && shape != null) {
getVisual().getChildren().remove(this.shape);
this.shape = shape;
if (shape instanceof GeometryNode) {
((GeometryNode<?>) shape).setStrokeType(StrokeType.INSIDE);
} else if (shape instanceof Shape) {
((Shape) shape).setStrokeType(StrokeType.INSIDE);
}
if (!shape.getStyleClass().contains(CSS_CLASS_SHAPE)) {
shape.getStyleClass().add(CSS_CLASS_SHAPE);
}
getVisual().getChildren().add(0, shape);
}
}
public LoadingCircle() {
Circle circle = new Circle(20);
circle.setFill(null);
circle.setStroke(Color.WHITE);
circle.setStrokeWidth(2);
Rectangle rect = new Rectangle(20, 20);
Shape shape = Shape.subtract(circle, rect);
shape.setFill(Color.WHITE);
getChildren().add(shape);
animation = new RotateTransition(Duration.seconds(2.5), this);
animation.setByAngle(-360);
animation.setInterpolator(Interpolator.LINEAR);
animation.setCycleCount(Animation.INDEFINITE);
animation.play();
}
@Override
protected void calculateShape() {
double cx = getCenterX();
double cy = getCenterY();
double r = getRadius();
double n = validateRoundness(getRoundness());
double w = validateWidth(getWidth(), r);
double arcWH = w * n;
Rectangle beam1 = new Rectangle(cx - r, cy - (w / 2), r * 2, w);
Rectangle beam2 = new Rectangle(cx - (w / 2), cy - r, w, r * 2);
beam1.setArcWidth(arcWH);
beam1.setArcHeight(arcWH);
beam2.setArcWidth(arcWH);
beam2.setArcHeight(arcWH);
Shape shape = Shape.union(beam1, beam2);
shape.getStyleClass().addAll("silhouette", "silhoutte-cross");
setShape(shape);
}
private void addMotionBlurEffect(Shape organShape, double zoomLevel, boolean effectsOn) {
organShape.setEffect(null);
if (!effectsOn)
return;
if (zoomLevel < MOTION_BLUR_DISTANCE)
return;
Vector movement = calculateMovement();
if (movement.equals(Vector.ZERO))
return;
double velocity = movement.getLength();
if (velocity < MOTION_BLUR_THRESHOLD)
return;
try {
organShape.setEffect(new MotionBlur(movement.getAngle(), velocity / MOTION_BLUR_THRESHOLD * MOTION_BLUR_INTENSITY));
} catch (ZeroVectorAngleException e) {
}
}
BaseShape( BasicView view, Supplier<Shape> buildRootShape) {
this.view = view;
rootShape = buildRootShape.get();
view.select(rootShape);
// select shape on click
Disposable disposable = JavaFxObservable.eventsOf(rootShape, MouseEvent.MOUSE_CLICKED)
.subscribe( e -> {
view.select(rootShape);
e.consume();
});
// dispose "listeners" when shape is removed from the scene
JavaFxObservable.changesOf(rootShape.sceneProperty())
.filter( scene -> scene == null )
.subscribe( s -> disposable.dispose());
// calculate delta between shape location and initial mouse position on mouse pressed
JavaFxObservable
.eventsOf( rootShape, MouseEvent.MOUSE_PRESSED )
.map( e -> new Point2D( e.getSceneX(), e.getSceneY()))
.subscribe( p -> {
view.select(rootShape);
Bounds bounds = rootShape.localToScene(rootShape.getLayoutBounds());
delta = p.subtract( new Point2D(bounds.getMinX(), bounds.getMinY()) );
});
// User current mouse position and delta to recalculate and set new shape location on mouse dragged
JavaFxObservable
.eventsOf( rootShape, MouseDragEvent.MOUSE_DRAGGED )
.map( e -> rootShape.sceneToLocal(e.getSceneX() - delta.getX(), e.getSceneY() - delta.getY()))
.map( p -> rootShape.localToParent(p))
.subscribe( p -> rootShape.relocate( p.getX(), p.getY()));
}
public void toggleSelected() {
isSelected = !isSelected;
final Color stroke = isSelected ? TargetRegion.SELECTED_STROKE_COLOR : TargetRegion.UNSELECTED_STROKE_COLOR;
for (final Node node : getTargetGroup().getChildren()) {
if (!(node instanceof TargetRegion)) continue;
final TargetRegion region = (TargetRegion) node;
if (region.getType() != RegionType.IMAGE) {
((Shape) region).setStroke(stroke);
}
}
if (isSelected) {
addResizeAnchors();
} else {
getTargetGroup().getChildren().removeAll(resizeAnchors);
resizeAnchors.clear();
}
if (selectionListener != null) selectionListener.targetSelected(this, isSelected);
}
private Shape makeSquare(Color colour, Color border) {
Stop[] stops = new Stop[]{new Stop(0, colour), new Stop(0.95, colour.deriveColor(1, 1, .75, 1)), new Stop(1.0, colour.deriveColor(1, 1, 0.5, 1))};
LinearGradient gradient = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops);
Rectangle square = new Rectangle(SQUARE_SIZE, SQUARE_SIZE);
square.setStroke(border);
square.setFill(gradient);
return square;
}
public static Shape getToolBarShape(final double width, final double height, final double radii) {
final double centreX = 0.0;
final double centreY = 0.0;
final double halfWidth = 0.5 * width + 2 * radii;
final double halfHeight = 0.5 * height;
Path path = new Path();
// go to left-top most corner
path.getElements().add(new MoveTo(centreX - halfWidth - 4 * radii, centreY - halfHeight));
// cubic sweep down
path.getElements().add(new CubicCurveTo(//
centreX - halfWidth - 2 * radii, centreY - halfHeight, // first control point
centreX - halfWidth - 2 * radii, centreY + halfHeight, // second control point
centreX - halfWidth, centreY + halfHeight)); // to coordinate
// line on bottom
path.getElements().add(new LineTo(centreX + halfWidth, centreY + halfHeight));
// cubic sweep up
path.getElements().add(new CubicCurveTo(//
centreX + halfWidth + 2 * radii, centreY + halfHeight, // first control point
centreX + halfWidth + 2 * radii, centreY - halfHeight, // second control point
centreX + halfWidth + 4 * radii, centreY - halfHeight)); // to coordinate
// return to top left corner
path.getElements().add(new LineTo(centreX - halfWidth - 2 * radii, centreY - halfHeight));
return path;
}
private Shape createPiece() {
Shape shape = createPieceRectangle();
if (hasRightTab) {
shape = Shape.union(shape,
createPieceTab(69.5f, 0f, 10f, 17.5f, 50f, -12.5f, 11.5f,
25f, 56.25f, -14f, 6.25f, 56.25f, 14f, 6.25f));
}
if (hasBottomTab) {
shape = Shape.union(shape,
createPieceTab(0f, 69.5f, 17.5f, 10f, -12.5f, 50f, 25f,
11f, -14f, 56.25f, 6.25f, 14f, 56.25f, 6.25f));
}
if (hasLeftTab) {
shape = Shape.subtract(shape,
createPieceTab(-31f, 0f, 10f, 17.5f, -50f, -12.5f, 11f,
25f, -43.75f, -14f, 6.25f, -43.75f, 14f, 6.25f));
}
if (hasTopTab) {
shape = Shape.subtract(shape,
createPieceTab(0f, -31f, 17.5f, 10f, -12.5f, -50f, 25f,
12.5f, -14f, -43.75f, 6.25f, 14f, -43.75f, 6.25f));
}
shape.setTranslateX(correctX);
shape.setTranslateY(correctY);
shape.setLayoutX(50f);
shape.setLayoutY(50f);
return shape;
}
private void createBackgroundTextures() {
final int tileSize = 600;
// TODO: remove this duplication
Group backgroundGroup = new Group();
Scene offScreenBackgroundScene = new Scene(backgroundGroup, tileSize, tileSize);
Shape emptySpace = new Rectangle(0, 0, tileSize, tileSize);
emptySpace.setFill(EnvironmentView.BACKGROUND_COLOR);
backgroundGroup.getChildren().add(emptySpace);
Group infraredBackgroundGroup = new Group();
Scene offScreenInfraredBackgroundScene = new Scene(infraredBackgroundGroup, tileSize, tileSize);
Shape infraredEmptySpace = new Rectangle(0, 0, tileSize, tileSize);
infraredEmptySpace.setFill(EnvironmentView.INFRARED_BACKGROUND_COLOR);
infraredBackgroundGroup.getChildren().add(infraredEmptySpace);
for (int i = 0; i < 5; i++) {
int x = getRandomCoordinate(tileSize);
int y = getRandomCoordinate(tileSize);
backgroundGroup.getChildren().add(createSpeckle(x, y, NORMAL_SPECKLE_RADIUS));
infraredBackgroundGroup.getChildren().add(createSpeckle(x, y, INFRARED_SPECKLE_RADIUS));
}
backgroundTexture = new WritableImage(tileSize, tileSize);
offScreenBackgroundScene.snapshot(backgroundTexture);
infraredBackgroundTexture = new WritableImage(tileSize, tileSize);
offScreenInfraredBackgroundScene.snapshot(infraredBackgroundTexture);
}
private void setGroupColor(Group group, Color color) {
if (group != null) {
for(Node child: group.getChildren()) {
if (child instanceof Shape) {
((Shape)child).setFill(color);
} else if (child instanceof Group) {
setGroupColor((Group)child,color);
}
}
}
}
/**
* this method is used to set some nodes in cell content as mouse transparent nodes
* so clicking on them will trigger the ripple effect.
*/
protected void makeChildrenTransparent() {
for (Node child : getChildren()) {
if (child instanceof Label) {
Set<Node> texts = child.lookupAll("Text");
for (Node text : texts) {
text.setMouseTransparent(true);
}
} else if (child instanceof Shape) {
child.setMouseTransparent(true);
}
}
}
private void setGroupColor(Group group, Color color) {
if (group != null) {
for(Node child: group.getChildren()) {
if (child instanceof Shape) {
((Shape)child).setFill(color);
} else if (child instanceof Group) {
setGroupColor((Group)child,color);
}
}
}
}
@Test
void testShowPtsDotsOkColor() {
model.setShowPts(true);
model.setLineColour(ShapeFactory.INST.createColorFX(Color.RED));
WaitForAsyncUtils.waitForFxEvents();
assertThat(view.showPoint.getChildren())
.filteredOn(n -> n instanceof Ellipse)
.allMatch(elt -> Color.RED.equals(((Shape) elt).getFill()));
}
public static String shapeToSvgString(final Shape SHAPE) {
final StringBuilder fxPath = new StringBuilder();
if (Line.class.equals(SHAPE.getClass())) {
fxPath.append(convertLine((Line) SHAPE));
} else if (Arc.class.equals(SHAPE.getClass())) {
fxPath.append(convertArc((Arc) SHAPE));
} else if (QuadCurve.class.equals(SHAPE.getClass())) {
fxPath.append(convertQuadCurve((QuadCurve) SHAPE));
} else if (CubicCurve.class.equals(SHAPE.getClass())) {
fxPath.append(convertCubicCurve((CubicCurve) SHAPE));
} else if (Rectangle.class.equals(SHAPE.getClass())) {
fxPath.append(convertRectangle((Rectangle) SHAPE));
} else if (Circle.class.equals(SHAPE.getClass())) {
fxPath.append(convertCircle((Circle) SHAPE));
} else if (Ellipse.class.equals(SHAPE.getClass())) {
fxPath.append(convertEllipse((Ellipse) SHAPE));
} else if (Text.class.equals(SHAPE.getClass())) {
Path path = (Path)(Shape.subtract(SHAPE, new Rectangle(0, 0)));
fxPath.append(convertPath(path));
} else if (Path.class.equals(SHAPE.getClass())) {
fxPath.append(convertPath((Path) SHAPE));
} else if (Polygon.class.equals(SHAPE.getClass())) {
fxPath.append(convertPolygon((Polygon) SHAPE));
} else if (Polyline.class.equals(SHAPE.getClass())) {
fxPath.append(convertPolyline((Polyline) SHAPE));
} else if (SVGPath.class.equals(SHAPE.getClass())) {
fxPath.append(((SVGPath) SHAPE).getContent());
}
return fxPath.toString();
}
@Test
void testShowPtsCtrlLineSizeDbleLine() {
model.setShowPts(true);
model.setHasDbleBord(true);
model.setDbleBordSep(12d);
model.setThickness(5d);
WaitForAsyncUtils.waitForFxEvents();
assertThat(view.showPoint.getChildren())
.filteredOn(n -> n instanceof Line)
.allMatch(elt -> MathUtils.INST.equalsDouble(((Shape) elt).getStrokeWidth(), 11d));
}
@Override
public void init() {
double t = 0;
for (int y = 0; y < ENEMY_ROWS; y++) {
for (int x = 0; x < ENEMIES_PER_ROW; x++) {
Entity enemy = spawnEnemy(50, 50);
var path = new Rectangle(Config.WIDTH - 100, Config.HEIGHT / 2.0);
path.setX(50);
path.setY(50);
var inter = new Rectangle(Config.WIDTH - 100, Config.HEIGHT);
inter.setX(50);
inter.setY(50);
var a = animationBuilder()
.repeatInfinitely()
.delay(Duration.seconds(t))
.duration(Duration.seconds(2.5))
.translate(enemy)
// TODO: remove intersection
.alongPath(Shape.intersect(inter, path))
.build();
animations.add(a);
a.start();
t += 0.3;
}
}
}
private static void updateShapeAppearance( Shape shape, boolean selected ) {
if ( shape == null ) return;
shape.setFill(selected ? Color.LIGHTGREEN : Color.LIGHTBLUE);
shape.setStroke(Color.DARKGRAY);
shape.setStrokeWidth(2.5);
DropShadow shadow = new DropShadow();
shadow.setOffsetY(3.0);
shadow.setOffsetX(3.0);
shadow.setColor(Color.GRAY);
shape.setEffect(shadow);
}
@Override
public void init() {
double t = 0;
for (int y = 0; y < ENEMY_ROWS; y++) {
for (int x = 0; x < ENEMIES_PER_ROW; x++) {
Entity enemy = spawnEnemy(50, 50);
var path = new Rectangle(Config.WIDTH - 100, Config.HEIGHT / 2.0);
path.setX(50);
path.setY(50);
var inter = new Rectangle(Config.WIDTH - 100, Config.HEIGHT);
inter.setX(50);
inter.setY(50);
var a = animationBuilder()
.repeatInfinitely()
.delay(Duration.seconds(t))
.duration(Duration.seconds(2.5))
.translate(enemy)
// TODO: remove intersection
.alongPath(Shape.intersect(inter, path))
.build();
animations.add(a);
a.start();
t += 0.3;
}
}
}
@Override protected void handleEvents(final String EVENT_TYPE) {
super.handleEvents(EVENT_TYPE);
if ("VISIBILITY".equals(EVENT_TYPE)) {
title.setVisible(getSkinnable().isTitleVisible());
title.setManaged(getSkinnable().isTitleVisible());
text.setVisible(getSkinnable().isTextVisible());
text.setManaged(getSkinnable().isTextVisible());
dateText.setVisible(getSkinnable().isDateVisible());
dateText.setManaged(getSkinnable().isDateVisible());
second.setVisible(getSkinnable().isSecondsVisible());
second.setManaged(getSkinnable().isSecondsVisible());
boolean alarmsVisible = getSkinnable().isAlarmsVisible();
for (Shape shape : alarmMap.values()) {
shape.setManaged(alarmsVisible);
shape.setVisible(alarmsVisible);
}
} else if ("SECTION".equals(EVENT_TYPE)) {
sections = getSkinnable().getSections();
highlightSections = getSkinnable().isHighlightSections();
sectionsVisible = getSkinnable().getSectionsVisible();
areas = getSkinnable().getAreas();
highlightAreas = getSkinnable().isHighlightAreas();
areasVisible = getSkinnable().getAreasVisible();
redraw();
} else if ("FINISHED".equals(EVENT_TYPE)) {
}
}
public ImagePattern apply(final Shape SHAPE) {
double x = SHAPE.getLayoutBounds().getMinX();
double y = SHAPE.getLayoutBounds().getMinY();
double width = SHAPE.getLayoutBounds().getWidth();
double height = SHAPE.getLayoutBounds().getHeight();
centerX = width * 0.5;
centerY = height * 0.5;
return new ImagePattern(getImage(width, height), x, y, width, height, false);
}
private static void setRotate(Shape s, boolean reverse, double angle, int duration) {
RotateTransition r = new RotateTransition(Duration.seconds(duration), s);
r.setAutoReverse(reverse);
r.setDelay(Duration.ZERO);
r.setRate(3.0);
r.setCycleCount(RotateTransition.INDEFINITE);
r.setByAngle(angle);
r.play();
}
/**
* Returns the dot arrow shape decoration corresponding to the
* <i>arrowType</i> parameter.
*
* @param arrowType
* The arrow type for which the dot edge decoration should be
* determined.
*
* @param arrowSize
* The size of the arrow shape decoration.
*
* @param penwidth
* The (pen)width of the shape's drawn lines.
*
* @param color
* The color to use for the arrow shape decoration outline.
*
* @param fillColor
* The color to use for the arrow shape decoration background.
*
* @return The dot arrow shape decoration.
*/
static Node get(ArrowType arrowType, double arrowSize, Double penwidth,
String color, String fillColor) {
// The first arrow shape specified should occur closest to the node.
double offset = 0.0;
Group group = new Group();
for (AbstractArrowShape arrowShape : arrowType.getArrowShapes()) {
Shape currentShape = get(arrowShape, arrowSize, penwidth, color,
fillColor);
if (currentShape == null) {
// represent the "none" arrow shape with a transparent box with
// the corresponding size
currentShape = new Box(arrowSize);
currentShape.setFill(Color.TRANSPARENT);
currentShape.setTranslateX(offset);
} else {
if (currentShape instanceof Circle) {
// translate a circle-based shape specially because of its
// middle-point-based translation
currentShape.setTranslateX(offset
+ currentShape.getLayoutBounds().getWidth() / 2);
} else {
currentShape.setTranslateX(offset);
}
}
offset += NodeUtils.getShapeBounds(currentShape).getWidth()
- currentShape.getStrokeWidth();
group.getChildren().add(currentShape);
}
return group;
}