JavaFX

The JavaFX Print API

This is a JavaFX Print Example. JavaFX added support for printing nodes through the Print API in the javafx.print package. The API consists of the following classes:

  • Printer
  • PrinterAttributes
  • PrintResolution
  • PrinterJob
  • JobSettings
  • Paper
  • PaperSource
  • PageLayout
  • PageRange

Instances of the above-listed classes represent different parts of the printing process. For example, a Printer represents a printer that can be used for printing jobs. A PrinterJob represents a print job that can be sent to a Printer for printing. And a Paper represents the paper sizes available on printers.

 
The Print API provides support for printing nodes that may or may not be attached to a Scene Graph.

If a node is modified during the printing process, the printed node may not appear correct. Note that the printing of a Node may span multiple pulse events resulting in concurrent change in the content being printed. To ensure correct printing, please make sure that the Node being printed is not modified during the print process.

Nodes can be printed on any thread including the JavaFX Application Thread. It is recommended that large, time-consuming print jobs be submitted on a background thread to keep the UI responsive.

Classes in the Print API are final as they represent existing printing device properties. Most of them do not provide any public constructor as you cannot make up a printing device. Rather, you obtain their references using factory methods in various classes.

The following table shows an overview of the whole article:

The following examples uses Java SE 8 and JavaFX 2.2.

1. Listing Available Printers

1.1 The Code

FxPrintExample1.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import javafx.application.Application;
import javafx.collections.ObservableSet;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.Printer;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample1 extends Application
{
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(Stage stage)
    {
        // Create the TextArea
        final TextArea textArea = new TextArea();
        // Create the Button
        Button button = new Button("Get all Printers");
 
        // Create the Event-Handlers for the Buttons
        button.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                //Get all Printers
                ObservableSet<Printer> printers = Printer.getAllPrinters();
                 
                for(Printer printer : printers)
                {
                    textArea.appendText(printer.getName()+"\n");
                }      
            }
        });
         
        // Create the VBox with a 10px spacing
        VBox root = new VBox(10);  
        // Add the Children to the VBox
        root.getChildren().addAll(button,textArea);
        // Set the Size of the VBox
        root.setPrefSize(400, 250);    
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("Showing all Printers");
        // Display the Stage
        stage.show();      
    }
}

The Printer.getAllPrinters() static method returns an ObservableList of installed printers on the machine. Note that the list of printers returned by the method may change over time as new printers are installed or old printers are removed. Use the getName() method of the Printer to get the name of the printer.

The following snippet of code lists all installed printers on the machine running the code. You may get a different output.

1
2
3
4
5
6
7
//Get all Printers
ObservableSet<Printer> printers = Printer.getAllPrinters();
 
for(Printer printer : printers)
{
    textArea.appendText(printer.getName()+"\n");
}      

1.2 The GUI

The following GUI shows a list of all printers:

Showing all Printers with the JavaFX Print API
Showing all Printers with the JavaFX Print API

2. Getting the Default Printer

2.1 The Code

FxPrintExample2.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.Printer;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample2 extends Application
{
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(Stage stage)
    {
        // Create the TextArea
        final TextArea textArea = new TextArea();
        // Create the Button
        Button button = new Button("Get the Default Printer");
 
        // Create the Event-Handlers for the Buttons
        button.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                //Get the Default Printer
                Printer defaultprinter = Printer.getDefaultPrinter();
 
                if (defaultprinter != null)
                {
                    String name = defaultprinter.getName();
                    textArea.appendText("Default printer name: " + name);
                }
                else
                {
                    textArea.appendText("No printers installed.");
                }      
            }
        });
         
        // Create the VBox with a 10px spacing
        VBox root = new VBox(10);  
        // Add the Children to the VBox
        root.getChildren().addAll(button,textArea);
        // Set the Size of the VBox
        root.setPrefSize(400, 250);    
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("Show the default Printer");
        // Display the Stage
        stage.show();      
    }
}

The Printer.getDefaultPrinter() method returns the default Printer. The method may return null if no printer is installed. The default printer may be changed on a machine. Therefore, the method may return different printers from call to call, and the printer returned may not be valid after some time.

The following snippet of code shows how to get the default Printer.

01
02
03
04
05
06
07
08
09
10
11
12
//Get the Default Printer
Printer defaultprinter = Printer.getDefaultPrinter();
 
if (defaultprinter != null)
{
    String name = defaultprinter.getName();
    textArea.appendText("Default printer name: " + name);
}
else
{
    textArea.appendText("No printers installed.");
}      

2.2 The GUI

The following image shows the default printer. In this case, it is a CutePDF Writer.

Get the Default Printer with the JavaFX Print API
Get the Default Printer with the JavaFX Print API

3. Printing Nodes

3.1 The Code

FxPrintExample3.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample3 extends Application
{
    // Create the JobStatus Label
    private Label jobStatus = new Label();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(Stage stage)
    {
        // Create the VBox
        final VBox root = new VBox(5);
 
        // Create the Text Label
        Label textLabel = new Label("Please insert your Text:");
         
        // Create the TextArea
        final TextArea textArea = new TextArea();
         
        // Create the Buttons
        Button printTextButton = new Button("Print Text");
        Button printSceneButton = new Button("Print Scene");
         
        // Create the Event-Handlers for the Buttons
        printTextButton.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                print(textArea);
            }
        });
 
        printSceneButton.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                print(root);
            }
        });
         
        // Create the Status Box
        HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
        // Create the Button Box
        HBox buttonBox = new HBox(5, printTextButton, printSceneButton);
 
        // Add the Children to the VBox    
        root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
        // Set the Size of the VBox
        root.setPrefSize(400, 300);    
         
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("A Printing Nodes Example");
        // Display the Stage
        stage.show();      
    }
     
    private void print(Node node)
    {
        // Define the Job Status Message
        jobStatus.textProperty().unbind();
        jobStatus.setText("Creating a printer job...");
         
        // Create a printer job for the default printer
        PrinterJob job = PrinterJob.createPrinterJob();
         
        if (job != null)
        {
            // Show the printer job status
            jobStatus.textProperty().bind(job.jobStatusProperty().asString());
             
            // Print the node
            boolean printed = job.printPage(node);
 
            if (printed)
            {
                // End the printer job
                job.endJob();
            }
            else
            {
                // Write Error Message
                jobStatus.textProperty().unbind();
                jobStatus.setText("Printing failed.");
            }
        }
        else
        {
            // Write Error Message
            jobStatus.setText("Could not create a printer job.");
        }
    }  
}

Printing a Node is easy. Create a PrinterJob and call its printPage() method passing the Node to be printed.

The details of the following code snippet will discuss in the next sentences.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Create a printer job for the default printer
PrinterJob job = PrinterJob.createPrinterJob();
 
if (job != null)
{
    // Show the printer job status
    jobStatus.textProperty().bind(job.jobStatusProperty().asString());
 
    // Print the node
    boolean printed = job.printPage(node);
 
    if (printed)
    {
        // End the printer job
        job.endJob();
    }
    else
    {
        // Write Error Message
        jobStatus.textProperty().unbind();
        jobStatus.setText("Printing failed.");
    }
}
else
{
    // Write Error Message
    jobStatus.setText("Could not create a printer job.");
}

You can use the createPrinterJob() static method of the PrinterJob class to create a printer job:

  • public static PrinterJob createPrinterJob()
  • public static PrinterJob createPrinterJob(Printer printer)

The method with no-args creates a printer job for the default printer. You can use the other version of the method to create a printer job for the specified printer.

You can change the printer for a PrinterJob by calling its setPrinter() method. If the current printer job settings are not supported by the new printer, the settings are reset automatically for the new printer.

Setting the Printer to null for the job will use the default printer. Use one of the following printPage() methods to print a Node:

  • boolean printPage(Node node)
  • boolean printPage(PageLayout pageLayout, Node node)

The first version of the method takes only the node to be printed as the parameter. It uses the default page layout for the job for printing.

The second version lets you specify a page layout for printing the Node. The specified PageLayout will override the PageLayout for the job and it will be used only for printing the specified node. For subsequent printing, the default PageLayout for the job will be used. You can create a PageLayout using the Printer class.

The printPage() method returns true if the printing was successful. Otherwise, it returns false. When you are done printing, call the endJob() method. The method returns true if the job can be successfully spooled to the printer queue. Otherwise, it returns false, which may indicate that the job could not be spooled or it was already completed. After successful completion of the job, the job can no longer be reused.

You can cancel a print job using the cancelJob() method of the PrinterJob. The printing may not be cancelled immediately, for example, when a page is in the middle of printing. The cancellation occurs as soon as possible. The method does not have any effect if,

  • The job has already been requested to be cancelled.
  • The job is already completed.
  • The job has an error.

A PrinterJob has a read-only status, which is defined by one of the constants of the PrinterJob.JobStatus enum:

  • NOT_STARTED
  • PRINTING
  • CANCELED
  • DONE
  • ERROR

The NOT_STARTED status indicates a new job. In this status, the job can be configured and printing can be initiated. The PRINTING status indicates that the job has requested to print at least one page and it has not terminated printing. In this status, the job cannot be configured.

The other three statuses, CANCELED, DONE, and ERROR, indicate the termination state of the job. Once the job is in one of these statuses, it should not be reused. There is no need to call the endJob() method when the status goes to CANCELED or ERROR. The DONE status is entered when the printing was successful and the endJob() method was called. The PrinterJob class contains a read-only jobStatus property that indicates the current status of the print job.

3.2 The GUI

The GUI of the above program shows how to print nodes. It displays a TextArea where you can enter text.

Two Buttons are provided: one prints the TextArea node and the other the entire Scene. When printing is initiated, the print job status is displayed in a Label.

Printing a Node or Text with the JavaFX Print API
Printing a Node or Text with the JavaFX Print API

After pressing the Print Button, the following dialog appears:

Choosing the File Destination of the Print Job with the JavaFX Print API
Choosing the File Destination of the Print Job with the JavaFX Print API

Now you can define the location and name of the document.

4. Showing the Page Setup

4.1 The Code

FxPrintExample4.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample4 extends Application
{
    // Create the JobStatus Label  
    private final Label jobStatus = new Label();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(final Stage stage)
    {
        // Create the Text Label
        Label textLabel = new Label("Please insert your Text:");
 
        // Create the TextArea
        final TextArea textArea = new TextArea();
 
        // Create the Buttons
        Button pageSetupButton = new Button("Page Setup and Print");
         
        // Create the Event-Handlers for the Button
        pageSetupButton.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                pageSetup(textArea, stage);
            }
        });
         
        // Create the Status Box
        HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
        // Create the Button Box
        HBox buttonBox = new HBox(pageSetupButton);
         
        // Create the VBox
        VBox root = new VBox(5);
 
        // Add the Children to the VBox    
        root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
        // Set the Size of the VBox
        root.setPrefSize(400, 300);    
         
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("A Printing Dialog Example");
        // Display the Stage
        stage.show();      
    }
     
    private void pageSetup(Node node, Stage owner)
    {
        // Create the PrinterJob
        PrinterJob job = PrinterJob.createPrinterJob();
         
        if (job == null)
        {
            return;
        }
         
        // Show the page setup dialog
        boolean proceed = job.showPageSetupDialog(owner);
         
        if (proceed)
        {
            print(job, node);
        }
    }
     
    private void print(PrinterJob job, Node node)
    {
        // Set the Job Status Message
        jobStatus.textProperty().bind(job.jobStatusProperty().asString());
         
        // Print the node
        boolean printed = job.printPage(node);
     
        if (printed)
        {
            job.endJob();
        }
    }  
}

The Print API allows users to interact with the printing process. Users can change the printer settings interactively before the printing is initiated. The API lets you show Page Setup and Print Setup dialogs for setting the page properties and printer settings for the job.

You can let the user configure the page layout by showing a Page Setup dialog. Use the
showPageSetupDialog(Window owner) method of the PrinterJob to show a Page Setup dialog. The user can set the page size, source, orientation, and margin. The dialog may allow the user to access other printing properties such as the list of printers.

Once the user confirms the settings on the dialog, the PrinterJob has the new settings. The method returns true if the user confirms the settings on the dialog. It returns false if the user cancels the dialog. It also returns false if the dialog cannot be displayed, such as when the job is not in the NOT_STARTED state.

The owner parameter to the method is the window that will be the owner of the dialog box. It can be null. If specified, the inputs to the window will be blocked while the dialog is displayed.

The following code snippet shows how to create a PageSetupDialog:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// Create the PrinterJob
PrinterJob job = PrinterJob.createPrinterJob();
 
if (job == null)
{
    return;
}
 
// Show the page setup dialog
boolean proceed = job.showPageSetupDialog(owner);
 
if (proceed)
{
    print(job, node);
}

4.2 The GUI

The following image shows an example of the Page Setup Dialog:

Definition of the Page Setup with the JavaFX Print API
Definition of the Page Setup with the JavaFX Print API

After pressing on the Page Setup and Print Button, the following dialog will appear:

Definition of the Page Setup with the JavaFX Print API
Definition of the Page Setup with the JavaFX Print API

Now you can define the format and other attributes.

5. Showing the Print Dialogs

5.1 The Code

FxPrintExample5.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample5 extends Application
{
    // Create the JobStatus Label  
    private final Label jobStatus = new Label();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(final Stage stage)
    {
        // Create the Text Label
        Label textLabel = new Label("Please insert your Text:");
 
        // Create the TextArea
        final TextArea textArea = new TextArea();
 
        // Create the Buttons
        Button printSetupButton = new Button("Print Setup and Print");
         
        // Create the Event-Handlers for the Button
        printSetupButton.setOnAction(new EventHandler ()
        {
            public void handle(ActionEvent event)
            {
                printSetup(textArea, stage);
            }
        });
         
        // Create the Status Box
        HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
        // Create the Button Box
        HBox buttonBox = new HBox(printSetupButton);
         
        // Create the VBox
        VBox root = new VBox(5);
 
        // Add the Children to the VBox    
        root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
        // Set the Size of the VBox
        root.setPrefSize(400, 300);    
         
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("A Printing Dialog Example");
        // Display the Stage
        stage.show();      
    }
     
    private void printSetup(Node node, Stage owner)
    {
        // Create the PrinterJob       
        PrinterJob job = PrinterJob.createPrinterJob();
     
        if (job == null)
        {
            return;
        }
 
        // Show the print setup dialog
        boolean proceed = job.showPrintDialog(owner);
         
        if (proceed)
        {
            print(job, node);
        }
    }
     
    private void print(PrinterJob job, Node node)
    {
        // Set the Job Status Message
        jobStatus.textProperty().bind(job.jobStatusProperty().asString());
         
        // Print the node
        boolean printed = job.printPage(node);
     
        if (printed)
        {
            job.endJob();
        }
    }  
}

You can use the showPrintDialog(Window owner) method to show a Print dialog where the user can modify the printer and settings for the PrinterJob. The return value and parameter of this method have meanings similar to that of the showPageSetupDialog() method.

The following code snippet shows how to create a Print Dialog:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// Create the PrinterJob       
PrinterJob job = PrinterJob.createPrinterJob();
 
if (job == null)
{
    return;
}
 
// Show the print setup dialog
boolean proceed = job.showPrintDialog(owner);
 
if (proceed)
{
    print(job, node);
}

5.2 The GUI

The following image shows an example of the Print Setup Dialog:

Definition of the Print Setup with the JavaFX Print API
Definition of the Print Setup with the JavaFX Print API

After pressing on the Print Setup and Print Button, the following dialog will appear:

Definition of the Print Setup with the JavaFX Print API
Definition of the Print Setup with the JavaFX Print API

Now you can define the printer, pages and other attributes.

6. Customizing PrinterJob Settings

6.1 The Code

FxPrintExample6.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
import java.util.Set;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.Collation;
import javafx.print.JobSettings;
import javafx.print.PageOrientation;
import javafx.print.PrintSides;
import javafx.print.Printer;
import javafx.print.PrinterAttributes;
import javafx.print.PrinterJob;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public class FxPrintExample6 extends Application
{
    // Create the TextArea
    final TextArea textArea = new TextArea();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(Stage stage)
    {
        // Create the Button
        Button button = new Button("Get all Printer Attributes");
         
        // Create the Event-Handlers for the Buttons
        button.setOnAction(new EventHandler <ActionEvent>()
        {
            public void handle(ActionEvent event)
            {
                printAttributes();
            }
        });
         
        // Create the VBox with a 10px spacing
        VBox root = new VBox(10);  
        // Add the Children to the VBox
        root.getChildren().addAll(button, textArea);   
        // Set the Size of the VBox
        root.setPrefSize(400, 250);    
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("Showing all Printer Attributes");
        // Display the Stage
        stage.show();          
    }
     
    private void printAttributes()
    {
        // Get the Default Printer
        Printer printer = Printer.getDefaultPrinter();
        // Get the Printer Attributes
        PrinterAttributes attribs = printer.getPrinterAttributes();
 
        // Read some printer attributes
        int maxCopies = attribs.getMaxCopies();
        PrintSides printSides = attribs.getDefaultPrintSides();
        Set<PageOrientation> orientations = attribs.getSupportedPageOrientations();
        Set<Collation> collations = attribs.getSupportedCollations();
         
        // Print the printer attributes
        textArea.appendText("Max. Copies: " + maxCopies + "\n");
        textArea.appendText("Print Sides: " + printSides + "\n");
        textArea.appendText("Supported Orientation: " + orientations + "\n");
        textArea.appendText("Supported Collations: " + collations + "\n");
         
        // Create a printer job for the default printer
        PrinterJob job = PrinterJob.createPrinterJob();
        // Get the JobSettings for the print job
        JobSettings jobSettings = job.getJobSettings();
         
        // Print the printer attributes
        textArea.appendText("Print Sides: " + jobSettings.getPrintSides() + "\n");
         
        // Set the printSides to DUPLEX
        jobSettings.setPrintSides(PrintSides.DUPLEX);
         
        // Print the printer attributes
        textArea.appendText("Print Sides: " + jobSettings.getPrintSides() + "\n");             
    }
}

The Print API contains two classes that are related to printer and printer job settings:

  • PrinterAttributes
  • JobSettings

A Printer has attributes, which indicate the printing capabilities of the printer. Examples of printer attributes are default paper size, supported paper sizes, maximum number of copies, and default collation.

A PrinterAttributes object encapsulates the attributes of a Printer. The Print API does not let you change the printer attributes as you cannot change the capabilities of a printer. You can only use its capabilities.

You cannot create a PrinterAttributes object directly. You need to get it from a Printer object using the getPrinterAttributes() method.

The following snippet of code prints some attributes of the default printer in the machine: You may get a different output.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// Get the Default Printer
Printer printer = Printer.getDefaultPrinter();
// Get the Printer Attributes
PrinterAttributes attribs = printer.getPrinterAttributes();
 
// Read some printer attributes
int maxCopies = attribs.getMaxCopies();
PrintSides printSides = attribs.getDefaultPrintSides();
Set<PageOrientation> orientations = attribs.getSupportedPageOrientations();
Set<Collation> collations = attribs.getSupportedCollations();
 
// Print the printer attributes
textArea.appendText("Max. Copies: " + maxCopies + "\n");
textArea.appendText("Print Sides: " + printSides + "\n");
textArea.appendText("Supported Orientation: " + orientations + "\n");
textArea.appendText("Supported Collations: " + collations + "\n");

A JobSettings contains the printer attributes to be used for a print job for a specific printer. You can obtain the JobSettings of a print job using the getJobSettings() method of the PrinterJob object. A JobSettings is a mutable object. It contains a property for each printer attribute that can be set for a print job. By default, its properties are initialized to the default properties of the printer. You can change the property that will be used for the current print job. If you change the property of a JobSettings that is not supported by the printer, the property reverts to the default value for the printer.

The following snippet of code sets the printSides property to DUPLEX. In this case, the printer supports only ONE_SIDED printing.

Therefore, the printSides property is set to ONE_SIDED, which is the default, and only supported printSides value by the printer. You may get a different output.

01
02
03
04
05
06
07
08
09
10
11
12
13
// Create a printer job for the default printer
PrinterJob job = PrinterJob.createPrinterJob();
// Get the JobSettings for the print job
JobSettings jobSettings = job.getJobSettings();
 
// Print the printer attributes
textArea.appendText("Print Sides: " + jobSettings.getPrintSides() + "\n");
 
// Set the printSides to DUPLEX
jobSettings.setPrintSides(PrintSides.DUPLEX);
 
// Print the printer attributes
textArea.appendText("Print Sides: " + jobSettings.getPrintSides() + "\n");             

For a print job, you can specify the page ranges using the pageRanges property of the JobSettings.

The pageRanges property is an array of PageRange. A PageRange has startPage and endPage properties that define the range.

6.2 The GUI

The following image shows an example how to get the Printer attributes:

Showing all Printer Attributes with the JavaFX Print API
Showing all Printer Attributes with the JavaFX Print API

7. Setting Page Layout

7.1 The Code

FxPrintExample7.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import javafx.print.JobSettings;
import javafx.print.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
 
public class FxPrintExample7 extends Application
{
    // Create the TextArea
    final TextArea textArea = new TextArea();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
     
    @Override
    public void start(Stage stage)
    {
        // Create the Button
        Button button = new Button("Get all Page Attributes");
         
        // Create the Event-Handlers for the Buttons
        button.setOnAction(new EventHandler ()
        {
            public void handle(ActionEvent event)
            {
                printAttributes();
            }
        });
         
        // Create the VBox with a 10px spacing
        VBox root = new VBox(10);  
        // Add the Children to the VBox
        root.getChildren().addAll(button, textArea);   
        // Set the Size of the VBox
        root.setPrefSize(400, 250);    
        // Set the Style-properties of the VBox
        root.setStyle("-fx-padding: 10;" +
                "-fx-border-style: solid inside;" +
                "-fx-border-width: 2;" +
                "-fx-border-insets: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-color: blue;");
         
        // Create the Scene
        Scene scene = new Scene(root);
        // Add the scene to the Stage
        stage.setScene(scene);
        // Set the title of the Stage
        stage.setTitle("Showing all Page Layout Attributes");
        // Display the Stage
        stage.show();          
    }
 
    private void printAttributes()
    {
        // Create the Printer Job
        PrinterJob printerJob = PrinterJob.createPrinterJob();
         
        // Get The Printer Job Settings
        JobSettings jobSettings = printerJob.getJobSettings();
         
        // Get the Page Layout
        PageLayout pageLayout = jobSettings.getPageLayout();
         
        // Get the Page Attributes
        double pgW = pageLayout.getPrintableWidth();
        double pgH = pageLayout.getPrintableHeight();
        double pgLM = pageLayout.getLeftMargin();
        double pgRM = pageLayout.getRightMargin();
        double pgTM = pageLayout.getTopMargin();
        double pgBM = pageLayout.getBottomMargin();
         
        // Show the Page Attributes
        textArea.appendText("Printable Width: " + pgW + "\n");             
        textArea.appendText("Printable Height: " + pgH + "\n");
        textArea.appendText("Page Left Margin: " + pgLM + "\n");   
        textArea.appendText("Page Right Margin: " + pgRM + "\n");  
        textArea.appendText("Page Top Margin: " + pgTM + "\n");
        textArea.appendText("Page Bottom Margin: " + pgBM + "\n"); 
         
        // Get The Printer
        Printer printer = printerJob.getPrinter();
        // Create the Page Layout of the Printer
        pageLayout = printer.createPageLayout(Paper.A4,
                PageOrientation.LANDSCAPE,Printer.MarginType.EQUAL);
         
        jobSettings.setPageLayout(pageLayout);
         
        // Get the Page Attributes
        pgW = pageLayout.getPrintableWidth();
        pgH = pageLayout.getPrintableHeight();
        pgLM = pageLayout.getLeftMargin();
        pgRM = pageLayout.getRightMargin();
        pgTM = pageLayout.getTopMargin();
        pgBM = pageLayout.getBottomMargin();
         
        // Show the Page Attributes
        textArea.appendText("Printable Width: " + pgW + "\n");             
        textArea.appendText("Printable Height: " + pgH + "\n");
        textArea.appendText("Page Left Margin: " + pgLM + "\n");   
        textArea.appendText("Page Right Margin: " + pgRM + "\n");  
        textArea.appendText("Page Top Margin: " + pgTM + "\n");
        textArea.appendText("Page Bottom Margin: " + pgBM + "\n");         
    }
     
}

An instance of the PageLayout class represents the page setup for a print job. By default, it is set to the printer default value. You have already seen setting up the page layout using the Page Setup dialog. A PageLayout encapsulates three things:

  • The paper size
  • The page orientation
  • The page margins

A PageLayout is used to configure the printable area of the page, which must lie within the printable area of the hardware. If a page is rendered outside the printable area of the hardware, the content is clipped. You cannot create a PageLayout object directly. You need to use one of the createPageLayout() methods of the Printer to get a PageLayout.

  • PageLayout createPageLayout(Paper paper, PageOrientation orient, double lMargin, double rMargin, double tMargin, double bMargin)
  • PageLayout createPageLayout(Paper paper, PageOrientation orient, Printer.MarginType mType)

The margins can be specified as numbers or as one of the following constants of the Printer.MarginType enum.

  • DEFAULT
  • EQUAL
  • EQUAL_OPPOSITES
  • HARDWARE_MINIMUM

The DEFAULT margin type requests default 0.75 inch on all sides.

The EQUAL margin type uses the largest of the four hardware margins on all four sides, so the margins are equal on all four sides.

The EQUAL_OPPOSITES margin type uses the larger of left and right hardware margins for the left and right sides, and the larger of the top and bottom hardware margins for the top and bottom sides.

The HARDWARE_MINIMUM requests that the minimum hardware allowed margins should be set on all sides.

The following snippet of code creates a PageLayout for A4 size paper, LANDSCAPE page orientation, and equal margins on all sides. The PageLayout is set to a print job.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// Get The Printer
Printer printer = printerJob.getPrinter();
// Create the Page Layout of the Printer
pageLayout = printer.createPageLayout(Paper.A4,
        PageOrientation.LANDSCAPE,Printer.MarginType.EQUAL);
 
jobSettings.setPageLayout(pageLayout);
 
// Get the Page Attributes
pgW = pageLayout.getPrintableWidth();
pgH = pageLayout.getPrintableHeight();
pgLM = pageLayout.getLeftMargin();
pgRM = pageLayout.getRightMargin();
pgTM = pageLayout.getTopMargin();
pgBM = pageLayout.getBottomMargin();

Sometimes, you want to know the size of the printable area on the page. You can get it using the getPrintableWidth() and getPrintableHeight() methods of the PageLayout. This is useful if you want to resize a node before printing, so it fits the printable area.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Create the Printer Job
PrinterJob printerJob = PrinterJob.createPrinterJob();
 
// Get The Printer Job Settings
JobSettings jobSettings = printerJob.getJobSettings();
 
// Get the Page Layout
PageLayout pageLayout = jobSettings.getPageLayout();
 
// Get the Page Attributes
double pgW = pageLayout.getPrintableWidth();
double pgH = pageLayout.getPrintableHeight();
double pgLM = pageLayout.getLeftMargin();
double pgRM = pageLayout.getRightMargin();
double pgTM = pageLayout.getTopMargin();
double pgBM = pageLayout.getBottomMargin();
 
// Show the Page Attributes
textArea.appendText("Printable Width: " + pgW + "\n");             
textArea.appendText("Printable Height: " + pgH + "\n");
textArea.appendText("Page Left Margin: " + pgLM + "\n");   
textArea.appendText("Page Right Margin: " + pgRM + "\n");  
textArea.appendText("Page Top Margin: " + pgTM + "\n");
textArea.appendText("Page Bottom Margin: " + pgBM + "\n"); 

7.2 The GUI

The following image shows an example how to get the page attributes:

Showing all Page Layout Attributes with the JavaFX Print API
Showing all Page Layout Attributes with the JavaFX Print API

8. Download Java Source Code

This was an example of javafx.print

Download
You can download the full source code of this example here: JavaFxPrintExample.zip

Andreas Pomarolli

Andreas has graduated from Computer Science and Bioinformatics at the University of Linz. During his studies he has been involved with a large number of research projects ranging from software engineering to data engineering and at least web engineering. His scientific focus includes the areas of software engineering, data engineering, web engineering and project management. He currently works as a software engineer in the IT sector where he is mainly involved with projects based on Java, Databases and Web Technologies.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Adewunmi Micheal
Adewunmi Micheal
6 years ago

The Best Full Tutorial on JavaFx Printing API

Scott
Scott
5 years ago

What about printing multiple pages which most print applications may require. Currently, when a node is passed to the printPage(node), it will only print the first page. It will not print remaining pages.

Katana
Katana
5 years ago

I copied your code and didn’t modify anything and run it in IntelliJ using JavaFX8. When I print the TextArea, I got a grey background. Is there any way to remove that background?

Hammed
3 years ago

what about printing file rather than node

Back to top button