KacemSys
KacemSys

Reputation: 111

JavaFX8 Print API : how to set correctly the Printable area

In my javafx application , I'm using JavaFX 8 printing API to print a node , i am getting problem of the printing area , despite i have set the pageLayout with A4 paper .... here is my code :

public static  void printNode(final Node node) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Printer printer = Printer.getDefaultPrinter();   
        PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, 0,0,0,0 );      
        PrinterJob job = PrinterJob.createPrinterJob();
        if (job != null  && job.showPrintDialog(node.getScene().getWindow()) ) { 
            boolean success = job.printPage(pageLayout, node);                   
            if (success) {
                job.endJob();
            }
        }

And here is a snapshot of the node that i want to print it is : enter image description here

and here is what i am getting when i print the node enter image description here

Upvotes: 6

Views: 7212

Answers (2)

smashbotica
smashbotica

Reputation: 13

EDIT (after Menai Ala Eddine remark): If you want to print a Region (child of Node and parent of all controls and panes and charts), then you can change the parameter Node with Region and use this solution: [END_EDIT]

Since I cannot add any comments, I will place my solution here. I modified @NwDx's answer (it didn't work for me, I ended up with some weird scaling) by setting prefSize of the node to the printing page layout size, with this line of code:

node.setPrefSize(pageLayout.getPrintableWidth(), pageLayout.getPrintableHeight());

The whole snippet now looks something like this:

public static void printNode(final Region region) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
    Printer printer = Printer.getDefaultPrinter();
    PageLayout pageLayout
        = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
    PrinterJob job = PrinterJob.createPrinterJob();

     region.setPrefSize(pageLayout.getPrintableWidth(), pageLayout.getPrintableHeight());
    if (job != null && job.showPrintDialog(region.getScene().getWindow())) {
      boolean success = job.printPage(pageLayout, region);
      if (success) {
        job.endJob();
      }
    }
  }

Upvotes: 0

aw-think
aw-think

Reputation: 4803

In your method you need to get the hardware able margins. Even if you set the margins to 0, your printer has a non printable margin around the sheet.

You can view the margins if you print them out:

System.out.println("PageLayout: " + pageLayout.toString());

And you are not able to set the margins to a value less than zero. So you need to scale your Node that would be printed. The node will be scaled, printed and then unscaled.

  public static void printNode(final Node node) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
    Printer printer = Printer.getDefaultPrinter();
    PageLayout pageLayout
        = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
    PrinterAttributes attr = printer.getPrinterAttributes();
    PrinterJob job = PrinterJob.createPrinterJob();
    double scaleX
        = pageLayout.getPrintableWidth() / node.getBoundsInParent().getWidth();
    double scaleY
        = pageLayout.getPrintableHeight() / node.getBoundsInParent().getHeight();
    Scale scale = new Scale(scaleX, scaleY);
    node.getTransforms().add(scale);

    if (job != null && job.showPrintDialog(node.getScene().getWindow())) {
      boolean success = job.printPage(pageLayout, node);
      if (success) {
        job.endJob();

      }
    }
    node.getTransforms().remove(scale);
  }

Inspired by the solution found here: https://carlfx.wordpress.com/2013/07/15/introduction-by-example-javafx-8-printing/

Upvotes: 8

Related Questions