我有一个 javafx TabPane,我希望能够打印它。 TabPane 有两个选项卡,我希望每个选项卡都打印在自己的页面上。我使用 onAction 函数在其中一个选项卡上创建了一个按钮,以运行名为 onPrint 的方法。该按钮将在一个选项卡中打印一个表格,在另一个选项卡中打印另一个表格。
printer.fxml 文件
<ScrollPane fx:id="assessment"/>
<Pane fx:id="printPane">
<TabPane prefHeight="900.0" prefWidth="937.0" tabClosingPolicy="UNAVAILABLE">
<Tab text="Issues">
<AnchorPane fx:id="issuesTab" minHeight="0.0" minWidth="0.0" prefHeight="519.0" prefWidth="585.0">
<Text text="here is some text" />
<Button fx:id="print" layoutX="82.0" layoutY="60.0" mnemonicParsing="false" onAction="#onPrint" text="print" />
</AnchorPane>
</Tab>
<Tab text="Function">
<AnchorPane fx:id="FunctionTab" prefHeight="400.0" prefWidth="600.0">
<Text text="here is some text"/>
</AnchorPane>
</Tab>
</Pane>
</Scrollpane>
我尝试了几种不同的方法来使其正常工作。我将在下面介绍它们。
打印机控制器文件如下:
public ScrollPane assessment;
public Pane printerPane;
public AnchorPane issuesTab;
public AnchorPane functionTab;
public void onPrint(ActionEvent event) {
printPane.getChildren().addAll(issuesTab, functionTab);
Printer printer = Printer.getDefaultPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
PrinterJob job = PrinterJob.createPrinterJob();
job.getJobSettings().setPageRanges(new PageRange(1, 2));
if (job.showPrintDialog(printPane.getScene().getWindow())){
boolean success = job.printPage(pageLayout, printPane);
if (success) {
job.endJob();
}
}
}
目前这可行,但它将两个表添加到彼此之上。我尝试使用 setPageRanges 函数来设置页面范围,但无法使其正常工作。
然后我想也许我需要为每个选项卡创建一个全新的窗格,然后将它们添加到一个组中,然后它将单独打印。
private Node toPrint;
private Node printAllPages(){
if(toPrint== null){
Group group = new Group();
group.getChildren().addAll(
new Pane(issuesTab),
new Pane(functionTab)
);
notToPrint = group;
}
return notToPrint;
}
public void onPrint(ActionEvent event) {
PrinterJob job = PrinterJob.createPrinterJob();
if(job.showPrintDialog(notToPrint.getScene().getWindow())){
boolean success = job.printPage(printAllPages());
if(success){
job.endJob();
}
}
}
然而,这会导致以下错误 - 原因为:java.lang.NullPointerException:无法调用“javafx.scene.Node.getScene()”,因为“this.notToPrint”为空。我也不认为这是正确的方法。
是否需要应用任何 Printer、PageLayout 或 PrinterJob 设置,以便每个 AnchorPane 都可以打印在单独的页面上?
所做的编辑:
根据 @SedJ601 关于如何解决此问题的建议。我浏览了他提供的链接并决定尝试这个 -
PrintController.java
public TabPane allTabs;
Printer printer = Printer.getDefaultPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
PrinterJob job = PrinterJob.createPrinterJob();
if(job.showPrintDialog(allTabs.getScene().getWindow())){
double pagePrintableHeight = pageLayout.getPrintableHeight();
double pagePrintableWidth = pageLayout.getPrintableWidth();
double scaleX = pagePrintableWidth / allTabs.getBoundsInParent().getWidth();
double localScale = scaleX;
double numberOfPages = Math.ceil((allTabs.getPrefWidth()) * localScale) / pagePrintableHeight;
System.out.println(numberOfPages);
for(int i = 0; i < numberOfPages; i++){ job.printPage(pageLayout, allTabs.get(i)); } job.endJob();
}else{
System.out.println("This did not work");
}
打印.fxml
<ScrollPane fx:id="assessment">
<TabPane fx:id="allTabs" prefHeight="900.0" prefWidth="937.0" tabClosingPolicy="UNAVAILABLE">
<Tab text="Issues">
<content>
<AnchorPane fx:id="issuesTab" minHeight="0.0" minWidth="0.0" prefHeight="519.0" prefWidth="585.0">
<Text text="some text" />
</AnchorPane>
</content>
</Tab>
<Tab text="Function">
<content>
<AnchorPane fx:id="functionTab" prefHeight="400.0" prefWidth="600.0">
<Text text="some text" />
</AnchorPane>
</content>
</Tab>
</TabPane>
但是,这仅打印第一个选项卡。我尝试将 numberOfPages 值设置为 10.0,但仍然只打印第一个选项卡。如何编辑 for 循环以循环遍历两个选项卡或更改 numberOfPages 以准确查找所有页面?
如果你只有两个
Tabs
那么我认为下面的代码应该可以工作。
public void onPrint(ActionEvent event) {
printPane.getChildren().addAll(issuesTab, functionTab);
Printer printer = Printer.getDefaultPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
PrinterJob job = PrinterJob.createPrinterJob();
job.getJobSettings().setPageRanges(new PageRange(1, 2));
if (job.showPrintDialog(printPane.getScene().getWindow())){
//if the number of tabs is variable use a loop and print each tab.
boolean success = job.printPage(pageLayout, issuesTab);
boolean successTwo = job.printPage(pageLayout, functionTab);
if (success && successTwo) {
job.endJob();
}
else{
System.out.println("Printing Error!");
}
}
}
我在这里输入了这段代码,但没有对其进行测试。可能有错误。