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

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.

//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

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.

//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

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.

// 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

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:

// 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

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:

// 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

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.

// 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.

// 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

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.

// 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.

// 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
4 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
2 years ago

what about printing file rather than node

Back to top button