JavaFX-是否可以将一个形状分为两个或多个形状?

问题描述 投票:0回答:2

例如,我有这个Path

import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class DivideShape extends javafx.application.Application {

    @Override
    public void start(Stage primaryStage) {
        var path = new Path(new MoveTo(200, 380), new LineTo(0, 300),
            new ArcTo(300, 300, 0, 300, 0, false, true), new LineTo(380,
                    200), new ArcTo(180, 180, 0, 200, 380, false, false));
        path.setFill(Color.BLUE);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(new Scene(new Pane(path)));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

enter image description here

而且我想将它分成5个部分(与分割比萨饼完全一样)

这可以使用Line来完成。

但是,这种方式看起来像5个对象,但实际上它仍然是1个对象。

是否可以将对象分为5 Paths,这样我就不必一一创建它们了?

谢谢

UPDATE:

当然,当我修改启动方法时。

@Override
public void start(Stage primaryStage) {
    var pane = new Pane();
    var moveTo = new MoveTo(200, 380);
    var lineTo = new LineTo(0, 300);
    var arc_big = 300;
    var arc_small = 180;
    for (var deg = 198; deg <= 270; deg += 18) {
        var path = new Path(moveTo, lineTo);
        lineTo = new LineTo(300 + arc_big * Math.cos(Math.toRadians(deg)), 300 + arc_big * Math.sin(Math.toRadians(deg)));
        path.getElements().add(new ArcTo(arc_big, arc_big, 0, lineTo.getX(), lineTo.getY(), false, true));
        var move = new MoveTo(380 + arc_small * Math.cos(Math.toRadians(deg)), 380 + arc_small * Math.sin(Math.toRadians(deg)));
        path.getElements().addAll(new LineTo(move.getX(), move.getY()),
        new ArcTo(arc_small, arc_small, 0, moveTo.getX(), moveTo.getY(), false, false));
        moveTo = move;
        path.setFill(Color.color(Math.random(), Math.random(), Math.random()));
        pane.getChildren().add(path);
    }
    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(new Scene(pane));
    primaryStage.show();
}

enter image description here

所以我将创建五个单独的Paths,但是代码太复杂了。这就是为什么我想知道是否可以将其分割(1个对象到5个对象)?

java javafx path shapes
2个回答
0
投票

您可以使用Arc对象而不是Path来实现在这段代码中,我制作了五个18度的弧线,并用淡入淡出的动画使路径透明。动画结束时,我从窗格子级中删除路径`

 package dividedshape;

 import javafx.animation.FadeTransition;
 import javafx.application.Application;
 import javafx.scene.Scene;
 import javafx.scene.layout.Pane;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.*;
 import javafx.stage.Stage;
 import javafx.util.Duration;

 public class DivideShape extends Application {

@Override
public void start(Stage primaryStage) {
  Path path = new Path(new MoveTo(500, 500), new LineTo(0, 500),
            new ArcTo(500, 500, 0, 500, 0, false, true), new LineTo(500, 
    500));
    path.setFill(Color.BLUE);
    Arc arc1 = new Arc(500,500,500,500,90,18);
    arc1.setType(ArcType.ROUND);
    arc1.setFill(Color.BLUE);
    arc1.setStroke(Color.BLACK);

    Arc arc2 = new Arc(500,500,500,500,108,18);
    arc2.setType(ArcType.ROUND);
    arc2.setFill(Color.BLUE);
    arc2.setStroke(Color.BLACK);

    Arc arc3 = new Arc(500,500,500,500,126,18);
    arc3.setType(ArcType.ROUND);
    arc3.setFill(Color.BLUE);
    arc3.setStroke(Color.BLACK);

    Arc arc4 = new Arc(500,500,500,500,144,18);
    arc4.setType(ArcType.ROUND);
    arc4.setFill(Color.BLUE);
    arc4.setStroke(Color.BLACK);

    Arc arc5 = new Arc(500,500,500,500,162,18);
    arc5.setType(ArcType.ROUND);
    arc5.setFill(Color.BLUE);
    arc5.setStroke(Color.BLACK);

    primaryStage.setTitle("Hello World!");
    Pane pane = new Pane(arc1,arc2,arc3,arc4,arc5,path);
    primaryStage.setScene(new Scene(pane));
    primaryStage.show();

    FadeTransition fadePath = new FadeTransition(Duration.seconds(10), path);
    fadePath.setFromValue(10);
    fadePath.setToValue(0);
    fadePath.play();
    fadePath.setOnFinished(e->{ pane.getChildren().remove(path);});


   }

     public static void main(String[] args) {
     launch(args);
     }
    }`

result after fade animation


0
投票

当代码变得也变得复杂复杂时,请考虑将其重构为简短的单一职责可重用方法:

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class ConvinienceMethodsExample extends Application {

    private static final double OUTER_RADIUS =300, INNER_RADIUS = 180, ORIGIN_X = 300, ORIGIN_Y = 300;
    private static final double START_ANGLE =20, END_ANGLE = 70, STEP_ANGEL = 10;

    @Override
    public void start(Stage primaryStage) {

        Group group = new Group();

        for(double angle =  START_ANGLE; angle < END_ANGLE ; angle += STEP_ANGEL ){

            Point2D innerArcStart = getPoint(INNER_RADIUS, angle);
            Point2D innerArcEnd = getPoint(INNER_RADIUS, angle + STEP_ANGEL);
            Point2D outerArcStart = getPoint(OUTER_RADIUS, angle);
            Point2D outerArcEnd = getPoint(OUTER_RADIUS, angle + STEP_ANGEL);
            var path = getPath(innerArcStart, innerArcEnd, outerArcStart, outerArcEnd);
            group.getChildren().add(path);
        }
        primaryStage.setScene(new Scene(new Pane(group)));
        primaryStage.show();
    }

    private Point2D getPoint(double radius, double angle){

        double x = ORIGIN_X - radius * Math.cos(Math.toRadians(angle));
        double y = ORIGIN_Y - radius * Math.sin(Math.toRadians(angle));
        return new Point2D(x, y);
    }

    private Shape getPath(Point2D innerArcStart, Point2D innerArcEnd, Point2D outerArcStart, Point2D outerArcEnd){
        var path = new Path(
                new MoveTo(innerArcStart.getX(), innerArcStart.getY()),
                new LineTo(outerArcStart.getX(), outerArcStart.getY()), //left line
                new ArcTo(OUTER_RADIUS, OUTER_RADIUS, 0, outerArcEnd.getX(), outerArcEnd.getY(), false, true), //outer arc
                new LineTo(innerArcEnd.getX(),innerArcEnd.getY()), //right line
                new ArcTo(INNER_RADIUS, INNER_RADIUS, 0, innerArcStart.getX(), innerArcStart.getY(), false, false)
                );
        path.setFill(Color.color(Math.random(), Math.random(), Math.random()));
        return path;
    }

    public static void main(String args[]){
        launch(args);
    }
} 

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.