Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
559 views
in Technique[技术] by (71.8m points)

java - JavaFX and SVG : drawing a line

I am using JavaFX to render some SVG stuff. I defined many methods, returning the paths of different SVG shapes (ellipsis, circle, rectangle, lines, etc). All of them seem to work, except the line method. JavaFX doesn't return an error (meaning that the path is probably correct), yet it doesn't draw anything. Here is my method.

public static SVGPath line(float startX, float endX, float startY, float endY, PositionType positionType)
{
    SVGPath path = new SVGPath();
    path.setContent(positionType.getMoveto()+startX+","+startY+positionType.getLineto("l")+endX+","+endY);    

    return path;    
}

The method getMoveto() returns either M or m, depending on the PositionType, and getLineto() returns either L or l.

Here is a sample method call :

SVGPath test2 = SVGPrimitives.line(20f, 30.1f, 23f, 89.21f, PositionType.ABSOLUTE);

And here is the path that's returned :

M20.0,23.0 L 30.1,89.21

It does seem valid to me, yet nothing is drawn...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

An SVGPath containing a single line encloses no area, so no pixels will be rendered. To see the effect, you can use setStroke() on the path, which "Defines parameters of a stroke that is drawn around the outline of a Shape."

image

root.getChildren().addAll(line(32), line(48), line(64));
…
private SVGPath line(int size) {
    SVGPath path = new SVGPath();
    path.setStroke(Color.BLUE);
    path.setContent("M0,0L" + size + "," + size + "z");
    return path;
}

The same applies to more complex paths shown here. In the example below, note the following

  • A path can be scaled as a function of the size; a slightly different effect can be achieved by altering the scale of the enclosing Pane, as shown here.

  • As an aid in composition, Java 8 makes it easier to pass a function as a parameter, as suggested here.

  • More complex paths can be constructed using an available SVG editor.

Finally, "Consider a builder when faced with many constructor parameters."

image

import java.util.function.IntFunction;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.SVGPath;
import javafx.stage.Stage;

/**
 * @see http://www.w3.org/TR/SVG/paths.html
 * @see http://raphaeljs.com/icons/
 */
public class SVGIcons extends Application {

    private static final int SIZE = 16;

    @Override
    public void start(Stage stage) {
        VBox root = new VBox(10);
        root.setAlignment(Pos.CENTER);
        root.setPadding(new Insets(10));
        root.getChildren().add(createRow(this::lines));
        root.getChildren().add(createRow(this::curve));
        root.getChildren().add(createRow(this::arc));
        Scene scene = new Scene(root);
        stage.setTitle("SVGIcons");
        stage.setScene(scene);
        stage.show();
    }

    private HBox createRow(IntFunction<SVGPath> path) {
        HBox row = new HBox(10);
        row.setAlignment(Pos.CENTER);
        for (int i = 2; i < 6; i++) {
            row.getChildren().add(path.apply(i * SIZE));
        }
        return row;
    }

    private SVGPath lines(int size) {
        SVGPath path = new SVGPath();
        path.setFill(Color.ALICEBLUE);
        path.setStroke(Color.BLUE);
        path.setContent("M0," + size + "L" + size / 2 + ",0 "
            + size + "," + size + " " + size / 2 + "," + 2 * size / 3 + "z");
        return path;
    }

    private SVGPath curve(int size) {
        SVGPath path = new SVGPath();
        path.setFill(Color.HONEYDEW);
        path.setStroke(Color.GREEN);
        path.setContent("M0,0Q" + size + ",0,"
            + size + "," + size + "L0," + size + "z");
        return path;
    }

    private SVGPath arc(int size) {
        SVGPath path = new SVGPath();
        path.setFill(Color.MISTYROSE);
        path.setStroke(Color.RED);
        path.setContent("M0,0A" + size / 2 + "," + size
            + ",0,1,0," + size + ",0z");
        return path;
    }

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...