JavaFX PrintAPI PaperSource Error

I am using JavaFx Print-Dialog to set up a print job. All properties will be saved in the PrinterJob # JobSettings variable, but when I get the paper source from the job. Sets the default paper source.

How can I get the paper source that I installed?

Here is a quick example:

public class PrinterPaperSourceTest extends Application { public static void main(String[] args) { launch( args ); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Printer"); Button btn = new Button(); btn.setText("Show Printer Settings "); btn.setOnAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { PrinterJob job = PrinterJob.createPrinterJob(Printer.getDefaultPrinter()); job.showPageSetupDialog(null); Alert alert = new Alert(AlertType.INFORMATION); PaperSource paperSource = job.getJobSettings().getPaperSource(); alert.setContentText("PaperSource: " + paperSource.getName()); alert.show(); } }); StackPane root = new StackPane(); root.getChildren().add(btn); primaryStage.setScene(new Scene(root, 300, 250)); primaryStage.show(); } } 
+7
java printing javafx
source share
3 answers

I have no answer, but I will try to explain why this is happening and why it will not be easy to fix. This behavior seems to depend on the specifications of the Internet Printing Protocol (IPP) and is due to how IPP is implemented by the Java print service API (to which the JavaFX print job is delegated). The following is a snippet from the Oracles technical note that explains the limitations of manually setting the paper source ( https://docs.oracle.com/javase/8/docs/technotes/guides/jps/spec/attributes.fm5.html ):

Media is an IPP attribute that identifies the medium on which printing is. The Media attribute is an important attribute to understand, but is relatively complex.

The Java print service API defines three subclasses of the abstract Media class to reflect the overloaded Media attribute in the IPP specification: MediaSizeName, MediaName, and MediaTray. All subclasses of Media have a category of Media, for which each subclass defines different standard attribute values. [...]

The value of the Media attribute is always a string, but since the attribute is overloaded, its value determines the type of media to which the attribute belongs. For example, a predefined set of IPP attribute values ​​includes the values ​​"a4" and "top-tray". If the Media parameter is set to "a4", the Media attribute refers to the paper size, but if the Media parameter is set to "top-tray", the Media attribute refers to the paper source. [...]

In most cases, applications will use either MediaSizeName or MediaTray. The MediaSizeName class lists media by size. The MediaTray class lists the paper trays on the printer, which typically includes the main tray and the manual feed tray. The IPP 1.1 specification does not provide for the simultaneous indication of both the size of the media and the media tray, which means, for example, that the application cannot request A4 paper from the bypass tray. A future revision of the IPP specification may provide a way to request more than one type of media at a time, in which case the JPS API is likely to be expanded to implement this change.

So, MediaTray (or paper source) is not an independent parameter and cannot be set if the Media attribute is already defined in one of two other ways ( MediaSizeName or MediaName ). This is exactly what happens with the page setup dialogs.

J2DPrinterJob class (from the com.sun.prism.j2d.print package) contains the dialogue code and updates the print job settings (I found this while debugging your application). The following is a method of this class that updates the paper source setting in the dialog box.

 private void updatePaperSource() { Media m = (Media)printReqAttrSet.get(Media.class); if (m instanceof MediaTray) { PaperSource s = j2dPrinter.getPaperSource((MediaTray)m); if (s != null) { settings.setPaperSource(s); } } } 

I tested different scenarios, and the result was the same: by the time updatePaperSource() started, the Media attribute was already defined as MediaSizeName . Therefore, instructions in the if branches are never executed, so the paper source is not updated.

I suspect that the paper type or paper size takes precedence over the paper source, and since the page setup dialog always determines the paper type (there is no "Automatic option"), it overloads the paper source selection to avoid an attribute conflict. This essentially makes this option useless.

It could be a bug in the JDK or an intentional design decision. In any case, I don’t see an easy way to solve this problem while in JavaFX, given that it comes from private methods in the internal Javas API.

+1
source share

The print API appeared in fx8.0. And he can print nodes. You can create a printer job with the javafx.print.PrinterJob class. But it prints only the area that is suitable for the printed page, and not the one that you are on the screen. Therefore, you need to make your page node (scale, translation, etc.) with your hands.

You can use this code. Hope this helps you.

 /** * Prints the current page displayed within the internal browser, not necessarily the {@link #presentationProperty()}. * If no printers are installed on the system, an awareness is displayed. */ public final void print() { final PrinterJob job = PrinterJob.createPrinterJob(); if (job != null) { if (job.showPrintDialog(null)) { if(this.getPresentation().getArchive() != null) { final String extension = ".".concat(this.getPresentation().getArchiveExtension()); final int indexOfExtension = this.getPresentation().getArchive().getName().indexOf(extension); final String jobName = this.getPresentation().getArchive().getName().substring(0, indexOfExtension); job.getJobSettings().setJobName(jobName); } job.getJobSettings().setPrintQuality(PrintQuality.HIGH); job.getJobSettings().setPageLayout(job.getPrinter().createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, 0, 0, 0, 0)); this.internalBrowser.getEngine().print(job); job.endJob(); } else { job.cancelJob(); } } else { DialogHelper.showError("No printer", "There is no printer installed on your system."); } } 

Link to the resource:

+2
source share

After many searches, I found a way to print to another tray with javafx, and that was the first thing I looked at, so I thought that this would be the best place to publish my solution, which may differ in different trays. was tray 2, it will also print all available trays

 private void printImage(Node node) { PrinterJob job = PrinterJob.createPrinterJob(); if (job != null) { JobSettings js = job.getJobSettings(); PaperSource papersource = js.getPaperSource(); System.out.println("PaperSource=" + papersource); PrinterAttributes pa = printer.getPrinterAttributes(); Set<PaperSource> s = pa.getSupportedPaperSources(); System.out.println("# of papersources=" + s.size()); if (s != null) { for (PaperSource newPaperSource : s) { System.out.println("newpapersource= " + newPaperSource); //Here is where you would put the tray name that is appropriate //in the contains section if(newPaperSource.toString().contains("Tray 2")) js.setPaperSource(newPaperSource); } } job.getJobSettings().setJobName("Whatever You want"); ObjectProperty<PaperSource> sources = job.getJobSettings().paperSourceProperty(); System.out.println(sources.toString()); boolean success = job.printPage(node); if (success) { System.out.println("PRINTING FINISHED"); job.endJob(); //Stage mainStage = (Stage) root.getScene().getWindow(); //mainStage.close(); } } } 

Here is my conclusion:

 PaperSource=Paper source : Automatic # of papersources=6 newpapersource= Paper source : newpapersource= Paper source : Manual Feed in Tray 1 newpapersource= Paper source : Printer auto select newpapersource= Paper source : Tray 1 newpapersource= Paper source : Tray 2 newpapersource= Paper source : Form-Source ObjectProperty [bean: Collation = UNCOLLATED Copies = 1 Sides = ONE_SIDED JobName = Whatever Page ranges = null Print color = COLOR Print quality = NORMAL Print resolution = Feed res=600dpi. Cross Feed res=600dpi. Paper source = Paper source : Tray 2 Page layout = Paper=Paper: Letter size=8.5x11.0 INCH Orient=PORTRAIT leftMargin=54.0 rightMargin=54.0 topMargin=54.0 bottomMargin=54.0, name: paperSource, value: Paper source : Tray 2] PRINTING FINISHED 
0
source share

All Articles