JavaFX 8缩放节点,用于打印而不更改显示的节点

时间:2017-07-11 15:55:05

标签: javafx

在JavaFX 8中,我使用printerJob.printPage()打印节点(例如,ScatterChart)。如果不进行缩放,则会裁剪打印的节点。如果我缩放打印,则打印节点正确适合页面,但缩放显示的节点。一个简单的解决方案是复制/克隆节点,但似乎不支持。有没有比缩放节点然后删除缩放更好的解决方案(这会导致显示的节点暂时重新缩放,这是不雅观的)?看起来打印图形将是JavaFX的基本操作。

1 个答案:

答案 0 :(得分:0)

你可以玩这个应用程序。它创建了图表的PNG。然后打印图表。我没有缩放图像。实际图像位于源文件夹中。您也可以使用Paint打开它并从那里打印。您还可以对打印机设置进行编码,以便在打印前显示打印机对话框。

import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import static java.awt.print.Printable.NO_SUCH_PAGE;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication145 extends Application
{

    final static String itemA = "A";
    final static String itemB = "B";
    final static String itemC = "F";
    @Override
    public void start(Stage stage) {
        final NumberAxis xAxis = new NumberAxis();
        final CategoryAxis yAxis = new CategoryAxis();
        final BarChart<Number, String> bc = new BarChart<Number, String>(xAxis, yAxis);
        bc.setTitle("Summary");
        xAxis.setLabel("Value");
        xAxis.setTickLabelRotation(90);
        yAxis.setLabel("Item");

        XYChart.Series series1 = new XYChart.Series();
        series1.setName("2003");
        series1.getData().add(new XYChart.Data(2, itemA));
        series1.getData().add(new XYChart.Data(20, itemB));
        series1.getData().add(new XYChart.Data(10, itemC));

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("2004");
        series2.getData().add(new XYChart.Data(50, itemA));
        series2.getData().add(new XYChart.Data(41, itemB));
        series2.getData().add(new XYChart.Data(45, itemC));

        XYChart.Series series3 = new XYChart.Series();
        series3.setName("2005");
        series3.getData().add(new XYChart.Data(45, itemA));
        series3.getData().add(new XYChart.Data(44, itemB));
        series3.getData().add(new XYChart.Data(18, itemC));

        Button button = new Button("Print Chart");
        button.setOnAction((event)->{printImage(saveAsPng(bc));});//Create the image and print it.

        VBox vbox = new VBox();
        vbox.getChildren().add(bc);

        StackPane stackPane = new StackPane();
        stackPane.getChildren().add(button);
        vbox.getChildren().add(stackPane);

        Scene scene = new Scene(vbox, 800, 600);
        bc.getData().addAll(series1, series2, series3);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

    public File saveAsPng(BarChart barChart) {
        WritableImage image = barChart.snapshot(new SnapshotParameters(), null);

        // TODO: probably use a file chooser here
        File file = new File("chart.png");

        try {
            ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
        } catch (IOException e) {
            // TODO: handle exception here
        }

        return file;
    }

    private void printImage(File file) {
        Image image = new Image(file.toURI().toString());
        java.awt.image.BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
        PrinterJob printJob = PrinterJob.getPrinterJob();
        printJob.setPrintable(new Printable() {
            @Override
            public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException                    {
                // Get the upper left corner that it printable
                int x = (int) Math.ceil(pageFormat.getImageableX());
                int y = (int) Math.ceil(pageFormat.getImageableY());
                if (pageIndex != 0) {
                    return NO_SUCH_PAGE;
                }
                graphics.drawImage(bufferedImage, x, y, bufferedImage.getWidth(), bufferedImage.getHeight(), null);

                return PAGE_EXISTS;
            }
        });
        try {
            printJob.print();
        } catch (PrinterException e1) {
            e1.printStackTrace();
        }
    }
}