【问题标题】:JavaFX: How to use the GraphicsContext method appendSVGPath(String svgpath)JavaFX:如何使用 GraphicsContext 方法 appendSVGPath(String svgpath)
【发布时间】:2015-06-03 19:37:05
【问题描述】:

我正在开发一个使用 SVG 的项目。目前,该程序将 SVG 作为 SVGPath 对象存储在 FXML 文件中。然后将该文件加载到一个组中,然后将其添加到屏幕上。在 FXML 文件中,大约有 300 个这样的 SVGPath。我相信这最终意味着场景图上有 300 个节点。

我最终将不得不增加 SVGPath 的数量,并且担心在场景中放置更多节点,因此我开始考虑改用 Cavas/GraphicsContext。

GraphicsContext 有一个方法 appendSVGPath(String svgpath),我想我可以用它在 cavas 上绘制我的 SVG,但我没有运气让它们出现。

我使用 Oracle 的 CanvasTest.java 文件作为起点: http://docs.oracle.com/javafx/2/canvas/jfxpub-canvas.htm

我修改了文件以包含以下方法:

private void appendSVG(GraphicsContext gc) {
     SVGPath svg = new SVGPath();
     svg.setContent("M 100 100 L 300 100 L 200 300 z");
     svg.setFill(Color.RED);
     svg.setStroke(Color.BLUE);
     gc.appendSVGPath(svg.getContent());
}

但我无法让形状出现在画布上。

完整的测试代码在这里:

package canvastest;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.SVGPath;
import javafx.stage.Stage;

public class CanvasTest extends Application {

private Canvas canvas = new Canvas(200, 200);
private GraphicsContext gc = canvas.getGraphicsContext2D();
private Group root = new Group();

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

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Canvas Test");

    appendSVG(gc);

//        SVGPath svg = new SVGPath();
//        svg.setContent("M 100 100 L 300 100 L 200 300 z");
//        svg.setFill(Color.RED);
//        svg.setStroke(Color.BLUE);

    root.getChildren().add(root);
    primaryStage.setScene(new Scene(root, 400, 400));
    primaryStage.show();
}

private void appendSVG(GraphicsContext gc) {
    SVGPath svg = new SVGPath();
    svg.setContent("M 100 100 L 300 100 L 200 300 z");
    svg.setFill(Color.RED);
    svg.setStroke(Color.BLUE);
    gc.appendSVGPath(svg.getContent());
}
}

如果我从一开始就取消注释 SVG 部分,并将 svg 添加到 root,那么 svg 将显示。

有没有人使用 appendSVGPath 取得任何成功?

【问题讨论】:

  • 这个评论对于这个问题来说有点离题,但只是提到以防你想考虑一种不同的方法(我什至没有说它是更好的方法——只是不同)。如果您使用 Canvas 的唯一原因是因为您担心节点的数量,则可以改为将形状添加到屏幕外场景,并将其快照到 Image 并将该图像渲染到 ImageView - 然后 JavaFX 不会不必处理持续管理所有这些节点,最初渲染和快照节点只是一次性的事情。
  • 在这种情况下,只启用 Group 节点的缓存可能会更容易。您可以通过提供适当的缓存提示来进一步调整缓存行为。这在过去帮助了我很多,并且比切换到其他提到的选项之一要容易得多。

标签: canvas svg javafx graphicscontext


【解决方案1】:

画布不像场景图,描边和填充路径不会自动发生。相反,您需要将路径段提供给画布,然后显式调用 fill()stroke() 以应用这些操作。有关详细信息,请参阅GraphicsContext javadoc 前面的“路径渲染”部分。

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class CanvasTest extends Application {

    private Canvas canvas = new Canvas(200, 200);
    private GraphicsContext gc = canvas.getGraphicsContext2D();

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

    @Override
    public void start(Stage stage) {
        appendSVG(gc);

        stage.setScene(new Scene(new Group(canvas)));
        stage.show();
    }

    private void appendSVG(GraphicsContext gc) {
        gc.setFill(Color.RED);
        gc.setStroke(Color.BLUE);
        gc.appendSVGPath("M 50 50 L 150 50 L 100 150 z");
        gc.fill();
        gc.stroke();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2017-09-07
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    相关资源
    最近更新 更多