Hier ist das Problem:Printing Knoten mit JavaFX
Ich muss derzeit eine a4, Landschaft Seite drucken „Teile“ meiner aktuellen JavaFX Szene enthält.
Die Teile ich habe, sind Teile eines BorderPane zu drucken, muss ich die Links, Mitte und unten Knoten drucken, so dass die gedruckte Seite sollte wie folgt aussehen:
Das Wichtigste zu Drucken ist der Mittelteil. Es muss so groß wie möglich sein. Grundsätzlich kann der linke Teil maximal 10% der Seitenbreite und der untere 10-15% der Seitenhöhe einnehmen. Das mittlere Element sollte also so gedehnt werden, dass 90% der (druckbaren) Seitenbreite und 85% der (druckbaren) Seitenhöhe erreicht werden.
Ich habe versucht, tatsächlich einige Lösungen ohne Erfolg ... Ich habe einen Druckknopf erstellen, die wie folgt wirkt:
PrinterJob job = PrinterJob.createPrinterJob();
BorderPane bpToPrint = new BorderPane();
bpToPrint.setLeft(sourceBorderPane.getLeft());
bpToPrint.setCenter(sourceBorderPane.getCenter());
bpToPrint.setBottom(sourceBorderPane.getBottom());
if(job != null && job.showPrintDialog(root.getScene().getWindow())){
Printer printer = job.getPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.HARDWARE_MINIMUM);
double scaleX = pageLayout.getPrintableWidth()/bpToPrint.getWidth();
double scaleY = pageLayout.getPrintableHeight()/bpToPrint.getHeight();
Scale scale = new Scale(scaleX, scaleY);
bpToPrint.getTransforms().add(scale);
boolean success = job.printPage(pageLayout, bpToPrint);
if(success){
job.endJob();
}
}
// Since I did "move" the nodes to the "bpToPrint" borderpane
// I have to put them back to the "source"
sourceBorderPane.setBottom(bpToPrint.getBottom());
sourceBorderPane.setLeft(bpToPrint.getLeft());
sourceBorderPane.setCenter(bpToPrint.getCenter());
Als ich dieses Stück Code versuchen, erhält der Drucker einen Auftrag, „druckt“ eine Seite ... Eine leere Seite! Nichts, was auf sie gedruckt ...
Wenn ich die „Waage“ Teil zu entfernen, ich habe etwas, das auf der Seite druckt, aber es macht nicht an die Seitengröße auf allen ...
Ich habe auch versuchen, die Knoten zu „Snapshot“, so kann ich ihre Attribute (Breite, Höhe) überprüfen, aber fanden keine Möglichkeit, „sie verketten“ und das Ergebnis drucken ...
// WritableImage myLeft = bPane.getLeft().snapshot(null,null);
// System.out.println("left item width : "+myLeft.getWidth()+" height : "+myLeft.getHeight());
// WritableImage myCenter = bPane.getCenter().snapshot(null,null);
// System.out.println("center item width : "+myCenter.getWidth()+" height : "+myCenter.getHeight());
// WritableImage myBottom = bPane.getBottom().snapshot(null,null);
// System.out.println("Bottom item width : "+myBottom.getWidth()+" height : "+myBottom.getHeight());
ich diese bekommen als Ausgangs (nur zur Information):
left item width : 112.0 height : 892.0
center item width : 1746.0 height : 892.0
bottom item width : 1858.0 height : 95.0
Danke für Hilfe/Lesen, jede Hilfe wirklich geschätzt.
01 Update:
Hier ist der "aktualisierte Code":
PrinterJob job = PrinterJob.createPrinterJob();
Node myLeft = root.getLeft();
Node myCenter = root.getCenter();
Node myBottom = root.getBottom();
//I will use a HBox to put the left & center, and a VBox to put hbox + bottom
VBox vToPrint = new VBox();
HBox hToPrint = new HBox();
hToPrint.getChildren().addAll(myLeft, myCenter);
vToPrint.getChildren().addAll(hToPrint,myBottom);
//Next lines come from the applyCss example
Group tempRoot = new Group();
Scene tempScene = new Scene(tempRoot);
tempRoot.getChildren().add(vToPrint);
tempRoot.applyCss();
tempRoot.layout();
if(job != null && job.showPrintDialog(root.getScene().getWindow())){
Printer printer = job.getPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.HARDWARE_MINIMUM);
double width = vToPrint.getWidth();
System.out.println("WIDTH : "+width);
//Output : 852.0
double height = vToPrint.getHeight();
System.out.println("HEIGHT : "+height);
//Output : 803.0
PrintResolution resolution = job.getJobSettings().getPrintResolution();
System.out.println("FEEDRESOLUTION : "+resolution.getFeedResolution());
//Output : 600
System.out.println("CROSSFEEDRESOLUTION : "+resolution.getCrossFeedResolution());
//Output : 600
width /= resolution.getFeedResolution();
System.out.println("NEW WIDTH : "+width);
//Output : 1.42
height /= resolution.getCrossFeedResolution();
System.out.println("NEW HEIGHT : "+height);
//Output : 1.3383333333333334
double scaleX = pageLayout.getPrintableWidth()/72/width;
System.out.println("SCALE X : "+scaleX);
//Output : 8.01056338028169
double scaleY = pageLayout.getPrintableHeight()/72/height;
System.out.println("SCALE Y : "+scaleY);
//Output : 5.935252677755962
Scale scale = new Scale(scaleX, scaleY);
vToPrint.getTransforms().add(scale);
boolean success = job.printPage(pageLayout, vToPrint);
if(success){
job.endJob();
}
}
root.setLeft(myLeft);
root.setCenter(myCenter);
root.setBottom(myBottom);
Das Ergebnis Druck zeigt nur die linke obere Ecke meines vToPrint Box, eine ganze A4-Seite gespannt .. ^^.
Und die Ausgabe von Breite/Höhe hier ist nicht die gleiche wie die Snapshot-Breite/Höhe früher ich habe ...
left item width : 112.0 height : 892.0
center item width : 1746.0 height : 892.0
bottom item width : 1858.0 height : 95.0
Das ist wirklich verwirrend ...
02 Update:
Neue versuchen, mit Schnappschüssen & imageViews:
PrinterJob job = PrinterJob.createPrinterJob();
WritableImage myLeftImg = root.getLeft().snapshot(null, null);
WritableImage myCenterImg = root.getCenter().snapshot(null, null);
WritableImage myBottomImg = root.getBottom().snapshot(null, null);
ImageView myLeftImgView = new ImageView();
ImageView myCenterImgView = new ImageView();
ImageView myBottomImgView = new ImageView();
myLeftImgView.setImage(myLeftImg);
myCenterImgView.setImage(myCenterImg);
myBottomImgView.setImage(myBottomImg);
VBox vToPrint = new VBox();
HBox hToPrint = new HBox();
hToPrint.getChildren().addAll(myLeftImgView, myCenterImgView);
vToPrint.getChildren().addAll(hToPrint, myBottomImgView);
Group myRoot = new Group();
Scene myScene = new Scene(myRoot);
myRoot.getChildren().add(vToPrint);
myRoot.applyCss();
myRoot.layout();
if(job != null && job.showPrintDialog(root.getScene().getWindow())){
Printer printer = job.getPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.HARDWARE_MINIMUM);
boolean success = job.printPage(pageLayout, vToPrint);
if(success){
job.endJob();
}
}
Ich habe den Maßstab Teil dieses Stück Code entfernen und es gibt mir tatsächlich die folgende Ausgabe auf Druck:
Update 03:
Jetzt komme ich zu einem Ergebnis, aber die Druckauflösung scheint zu scheitern. Statt/72 die Skala (wie in Update 01):
double scaleX = pageLayout.getPrintableWidth()/72/width;
Ich habe es teilen mit 600 (wie die resolution.getFeedResolution) ... Aber es wahrscheinlich falsch ist, da ich es schon mit 600 geteilt früher .. .:
width /= resolution.getFeedResolution();
// ...
double scaleX = pageLayout.getPrintableWidth()/width/600;
die "vToPrint" vbox auf einer A4-Quer Seite das Ergebnis druckt, aber die Auflösung ist wirklich, wirklich, wirklich, ... Bad! Das Ganze ist pixelig. Texte sind lesbar aber es ist etwas falsch mit der Druckauflösung ...
Ich habe auch versucht, einen Snapshot der Knoten zu drucken, also ich meine vToPrint VBox, dann Snapshot erstellen, und speichern Sie den Snapshot in eine .png-Datei. Das ist gut, die Auflösung ist gut. Das Problem ist also im Druck Teil jetzt ...
Die Node.applyCss Dokumentation sagt auch, bpToPrint machen versuchen die Wurzel eine Szene vor dem Aufruf von applyCss und Layout. – VGR
Ja, du hast Recht. Ich tat dies. Sie können den aktualisierten Code jetzt sehen ... – Julo0sS
@VGR Ich versuche tatsächlich, das gleiche zu tun, aber mit Snapshots und imageViews ... Dies löst das "Größen" -Differenzproblem. Aber die Skala ist völlig falsch. Wenn ich den Skalierungscode lasse, bekomme ich nur die obere linke Ecke auf einer Seite. Wenn ich den Maßstabscode entferne, bekomme ich eine gedruckte Seite mit etwa 1/4 der gewünschten Ausgabe auf einer A4-Seite ... – Julo0sS