2017-06-21 20 views
2

ここに問題があります:JavaFXでノードを印刷する

現在、私の現在のjavaFxシーンの "部品"を含むa4の横のページを印刷する必要があります。

私が印刷した部品はBorderPaneの一部であり、私が印刷されたページは次のようになりますので、左、中央および下のノードを印刷する必要があります。

Second A4 Template Image

に最も重要なことプリントはセンター部分です。できるだけ広い/高い必要があります。基本的に、左の部分はページ幅の最大10%を取ることができ、下端はページの高さの10-15%のようにすることができます。したがって、中央の項目は、(印刷可能な)ページ幅の90%と(印刷可能な)ページ高さの85%に合わせて伸びる必要があります。

I実際に成功せず、いくつかの解決策を試してみました...私はこのような働きを印刷ボタンを作成しました:私は、コードのこの部分をしようとすると

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()); 

、プリンタがジョブを受信し、「プリント」ページ...空白のページ!それに印刷され、何も...

私は「スケール」の部分を削除した場合、私はページに印刷何かを持っていますが、それがすべてでページサイズを尊重しません...

私もなかったです

// 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()); 

私は出力としてこれを取得...ノードの「スナップショット」しようとするので、私はそれらの属性(幅、高さ)を確認することができますが、「彼らをCONCAT」と結果を印刷する方法を見つけることができませんでした(情報のみ):

left item width : 112.0 height : 892.0 
center item width : 1746.0 height : 892.0 
bottom item width : 1858.0 height : 95.0 

ヘルプ/読んでいただきありがとうございました。

アップデート01:ここ

"更新されたコード" です:全体のA4ページを超える伸び

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); 

印刷結果は、私のvToPrintボックスのちょうど左上隅を示しては.. 。^^

そしてここ幅/高さの出力Iが早くなったスナップショットの幅/高さと同じではありません...

left item width : 112.0 height : 892.0 
center item width : 1746.0 height : 892.0 
bottom item width : 1858.0 height : 95.0 

これは本当に混乱しています...

アップデート02:

新しいスナップショットを試みる& 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(); 
    } 
} 

私は、コードのこの作品のスケールの一部を削除しなかったし、それは実際に私の印刷に次のような出力が得られます。

enter image description here

更新03:

ここで結果は出ますが、印刷解像度は失敗しているようです。代わりに/ 72スケールの(更新01のように):

double scaleX = pageLayout.getPrintableWidth()/72/width; 

私はそれを分割しなかった...しかし、それは、私はすでに以前の600でそれを分割するので、おそらく間違っている600(resolution.getFeedResolutionのように).. 。:

width /= resolution.getFeedResolution(); 
// ... 
double scaleX = pageLayout.getPrintableWidth()/width/600; 

結果はA4横ページの "vToPrint" VBOXを印刷するが、解像度は本当に、本当に、本当に、...悪いです!全体がピクセル化されています。テキストは読み込み可能ですが、印刷解像度には何か問題があります...

vToPrint VBoxを作成してスナップショットを作成してから、印刷するノードのスナップショットを作成しようとしました。 .pngファイル。これは良いですが、解像度は問題ありません。だから、問題は ⁄ インチにそれらのサイズを返すgetPrintableHeight() ...今印刷部分に

+0

Node.applyCssのドキュメントでは、「ノードがシーンにない場合、このメソッドは何も行いません。」と言うbpToPrintのルート作ってみましょうapplyCssとレイアウトを呼び出す前のシーン。 – VGR

+0

ええ、そうです。これは私がしました。 – Julo0sS

+0

@VGR私は実際に同じことをしようとしていますが、スナップショットとimageViewsを使用しています...これは "サイズ"の違いの問題を解決します。しかし、規模は完全に間違っています。スケールコードを書き留めておけば、ページの左上隅のみが得られます。スケールコードを削除すると、a4ページの約1/4の出力が印刷されます。 – Julo0sS

答えて

1

は、溶液、多くの研究の後

であることは、問題が印刷に私が使用する「TEMP」コンテナから来ていることが表示されます。 applyCss()、layout()、またはautosize()が呼び出されても、本当にコンテナはレンダリングされません。

私が見つけた実際の解決策は、「本当の」コンテナを使用し、printJobを開始する前に印刷したくないアイテムを隠すことです。ここで

は、私が使用して現在のコードです:

PrinterJob job = PrinterJob.createPrinterJob(); 

if(job != null && job.showPrintDialog(root.getScene().getWindow())){ 
    Printer printer = job.getPrinter(); 
    PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.LANDSCAPE, Printer.MarginType.HARDWARE_MINIMUM); 

    root.getTop().setVisible(false); 
    root.getTop().setManaged(false); 

    double width = root.getWidth(); 
    double height = root.getHeight(); 

    PrintResolution resolution = job.getJobSettings().getPrintResolution(); 

    width /= resolution.getFeedResolution(); 

    height /= resolution.getCrossFeedResolution(); 

    double scaleX = pageLayout.getPrintableWidth()/width/600; 
    double scaleY = pageLayout.getPrintableHeight()/height/600; 

    Scale scale = new Scale(scaleX, scaleY); 

    root.getTransforms().add(scale); 

    boolean success = job.printPage(pageLayout, root); 
    if(success){ 
     job.endJob(); 
    } 
    root.getTransforms().remove(scale); 
} 
root.getTop().setManaged(true); 
root.getTop().setVisible(true); 
2

getPrintableWidth()です。 getWidth()およびgetHeight()はサイズをピクセル単位で返します。同等のユニットを分割する

、あなたはJobSettingsのprintResolutionプロパティを使用してインチにピクセルを変換することができます:

double width = bpToPrint.getWidth(); 
double height = bpToPrint.getHeight(); 

// Convert to inches 
PrintResolution resolution = job.getJobSettings().getPrintResolution(); 
width /= resolution.getFeedResolution(); 
height /= resolution.getCrossFeedResolution(); 

double scaleX = pageLayout.getPrintableWidth()/72/width; 
double scaleY = pageLayout.getPrintableHeight()/72/height; 

は、ノードののgetWidth(ことに注意してください)、それはではない場合のgetHeight()メソッドはゼロを返すことがあり可視段階、the documentation of Node.applyCss()に記載されているように、そのapplyCss()layout()方法は、最初に呼び出されない限り:

より完全な例として、次のコードは、applyCss()及びを使用しますをクリックして、ステージが表示される前にボタンの幅と高さを確認します。 applyCss()への呼び出しまたはlayout()への呼び出しのいずれかがコメントアウトされている場合、getWidth()getHeight()へのコールはゼロ(ステージが表示された後のある時間まで)を返します。ここで

+1

jewelseaはここの最後の部分を記述しています:https://stackoverflow.com/ a/26152904/2991525 – fabian

+0

あなたのアドバイスをお寄せいただきありがとうございました.VGR&Fabianにお役に立てれますが、解決策は依然として適切に機能していません。更新された投稿をチェックして、何が起こっているのかを確認してください。 – Julo0sS

+0

解像度(インチ、dpi、...)はどこか間違っているようです。 VBoxは現在ページ全体に印刷されていますが、すべてがピクセル化されています...:/それはまだ私にとっては本当に混乱しています。私のポストを更新しました。 – Julo0sS

関連する問題