JavaFX: How can a Path be painted on a GraphicsContext?
Asked Answered
S

2

4

JavaFX provides both low-level path painting methods on a GraphicsContext and a high-level Path node.

I want to store shapes in classes and draw them in a GraphicsContext. The Path class seems convenient for me. I know, it is meant to be used as a node in the scene graph, but it contains all drawing elements I need.

I am looking for a method like GraphicsContext.fillPath(Path) but there is none.

Do I have to iterate over the Path elements by hand and translate them into low-level GraphicsContext methods, or did I miss something?

Stela answered 20/1, 2015 at 11:13 Comment(2)
Hello Andi, is it possible to save the path in a variable and set it to a lable or something like this? I don't understand your problem... In JavaFX it is possible to Bind your Data to a specific graphical Object like an Label. So you can do something like this: label.bind(StringPath) -> This Example is not the real code but it would work like this from the logical sideFaden
This won't answer your question, but it's an easier way. Can you add a canvas to a pane then draw nodes or shapes (like path) on the pane and whatever else on the canvas? That's what I do for some custom high speed graphs. It's also easier for moving nodes around because there seems to be no XOR drawing mode for the javafx canvas, unlike awt.Pennsylvanian
D
3

Do I have to iterate over the Path elements by hand and translate them into low-level GraphicsContext methods?

Yes. You will need to write a translator to take data extracted from a Path and invoke appropriate graphics context methods (see the Path Rendering methods), for example beginPath(), moveTo(), lineTo(), closePath(), fill, stroke(), etc.


Rather than using a Path, you could perhaps use an SVGPath. It is easy to translate an SVGPath from a Scene graph node data to a GraphicsContext method - you can just do gc.appendSVGPath(svgPath.getContent()).

Deficient answered 20/1, 2015 at 19:2 Comment(2)
Finally I wrote my own Path class, so that I can use it on all platforms for which I write the software (JavaFX, Java 2D, Android, GWT). It's very simple... Here are the data structures, and here is an example how the JavaFX renderer processes them. For performance reasons, the SVGPath from a String is no option for me.Stela
Nice clean implementation Andi. You can always answer your own questions.Deficient
S
0

I know, it comes a bit late, but here is a simple generic solution...

Since Path class is of type Node, you can use the method Node.snapshot() on your specific Path and then pass the generated WritableImage to GraphicsContext.drawImage().

Here's a simple code-snippet how to achieve this:

public void start(Stage primaryStage) {

    Pane pane = new Pane();
    Canvas canvas = new Canvas(70, 70);
    GraphicsContext gc = canvas.getGraphicsContext2D();
    pane.getChildren().add(canvas);
    Scene scene = new Scene(pane, 70, 70);
    primaryStage.setScene(scene);
    
    Path path = new Path(
            new MoveTo(10,10), 
            new LineTo(60,60), 
            new LineTo(60, 10), 
            new ClosePath());
    path.setStroke(Color.BLACK);
    path.setStrokeWidth(2.0);
    Bounds pathBounds = path.getLayoutBounds();
    WritableImage snapshot = new WritableImage(
            (int) pathBounds.getWidth(), (int) pathBounds.getHeight());
    SnapshotParameters snapshotParams = new SnapshotParameters();
    snapshot = path.snapshot(snapshotParams, snapshot);
    gc.drawImage(snapshot, pathBounds.getMinX(), pathBounds.getMinY());
    
    primaryStage.show();
}
Shick answered 7/2, 2021 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.