Eric
Eric

Reputation: 11

JavaFX - Converting chart to image

I have an XYChart, which displays the hours of the day on the X-axis. I would like to save a image (or pdf) of the whole chart. However when I display the chart, I cannot display it all, it's too big, therefore I only display a fraction (1/4 approximately).

I have found this code that allows me to do a snapshot of what is displayed in my pane :

@FXML
public void saveAsPng() {

    WritableImage image = chart.snapshot(new SnapshotParameters(), null);
    File file = new File(path);

    try {
        ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

However, I can't find a way to save the whole chart as an image, without displaying it?

Has someone found a way to do so?

Thank you very much for your help in advance!

Reference : http://code.makery.ch/blog/javafx-2-snapshot-as-png-image/

Upvotes: 0

Views: 1846

Answers (1)

Andy Nugent
Andy Nugent

Reputation: 874

This will take a node

  • change it's parent to be a fixed size anchor pane
  • put the anchor pane inside a scroll pane
  • open the scroll pane in an invisible JFrame window
  • save the node as an image
  • return the node back to it's previous parent.

I've used it with Charts so we can embed the images in reports, but should work with any Node.

void doResize(final Node node, final File file, final int aWidth, final int aHeight) {

    final AnchorPane anchorPane = new AnchorPane();
    anchorPane.setMinSize(aWidth, aHeight);
    anchorPane.setMaxSize(aWidth, aHeight);
    anchorPane.setPrefSize(aWidth, aHeight);

    final ScrollPane scrollPane = new ScrollPane();
    scrollPane.setContent(anchorPane);

    final JFXPanel fxPanel = new JFXPanel();
    fxPanel.setScene(new Scene(scrollPane));

    final JFrame frame = new JFrame();

    final Pane previousParentPane = (Pane) node.getParent();

    frame.setSize(new Dimension(64, 64));
    frame.setVisible(false);
    frame.add(fxPanel);

    anchorPane.getChildren().clear();
    AnchorPane.setLeftAnchor(node, 0.0);
    AnchorPane.setRightAnchor(node, 0.0);
    AnchorPane.setTopAnchor(node, 0.0);
    AnchorPane.setBottomAnchor(node, 0.0);
    anchorPane.getChildren().add(node);

    anchorPane.layout();

    try {
        final SnapshotParameters snapshotParameters = new SnapshotParameters();
        snapshotParameters.setViewport(new Rectangle2D(0.0, 0.0, aWidth, aHeight));
        ImageIO.write(SwingFXUtils.fromFXImage(anchorPane.snapshot(snapshotParameters, new WritableImage(aWidth, aHeight)), new BufferedImage(aWidth, aHeight, BufferedImage.TYPE_INT_ARGB)), "png", file);

    }
    catch (final Exception e) {
        e.printStackTrace();
    }
    finally {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                // Return the node back into it's previous parent
                previousParentPane.getChildren().clear();
                AnchorPane.setLeftAnchor(node, 0.0);
                AnchorPane.setRightAnchor(node, 0.0);
                AnchorPane.setTopAnchor(node, 0.0);
                AnchorPane.setBottomAnchor(node, 0.0);
                previousParentPane.getChildren().add(node);

                frame.dispose();
            }
        });
    }
}

Upvotes: 1

Related Questions