JavaFX 1.1 で印刷

プレゼンツールのことを javafx-ja の ML で話した時に、印刷機能があるといいですねというコメントをいただいたので、ちょっと調べてみました。

javafx-ja ML http://groups.google.co.jp/group/javafx-ja

実をいうと、JavaFX 1.1 には印刷の機能がありません。

でも、ご安心。Java の機能を使って印刷をすることができます。

Java で印刷する場合、java.awt.print.Printable もしくは java.awt.print.Pegeable のどちらかのインタフェースを実装したクラスを使って、print メソッドを実装します。

print メソッドの第 1 引数は java.awt.Graphics オブジェクトなので、コンポーネントの paint メソッド (もしくは print/printAll メソッド) をこの Graphics オブジェクトを引数にしてコールすれば OK。

後は、コンポーネントの paint メソッドをどうやってコールするかです。

これは 5/17 に書いたように Node オブジェクトから JSGPanel オブジェクトを取りだして、その JSGPanel の paint メソッドを呼べば大丈夫のようです。

以下に、サンプルのプログラムを載せておきます。5/17 と同じようにコンパイル時のクラスパスに Scenario.jar を加える必要があります。

ボタンをクリックすると、プリンタのダイアログを表示して、印刷します。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import javax.swing.JComponent;

import javafx.ext.swing.SwingButton;
import javafx.ext.swing.SwingLabel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

class FXPrintable extends Printable {
    public-init var comp: JComponent;

    public override function print(g: Graphics,
                                    pageformat: PageFormat,
                                    index: Integer): Integer {
        // 印刷可能領域分だけ原点を移動
        var offsetX = pageformat.getImageableX();
        var offsetY = pageformat.getImageableX();
        var g2d = g as Graphics2D;
        g2d.translate(offsetX, offsetY);

        if (index == 0) {
            comp.paint(g2d);
            return Printable.PAGE_EXISTS;
        } else {
            return Printable.NO_SUCH_PAGE;
        }
    }
};

class PrintableNode extends Group {
    public function print(): Void {
        var printable = FXPrintable {
            comp: this.impl_getSGNode().getPanel()
        }
        // プリンタダイアログを表示して印刷
        var job = PrinterJob.getPrinterJob();
        job.setPrintable(printable);
        job.printDialog();
    }
};

var node: PrintableNode = PrintableNode {
    content: [
        Rectangle {
            x: 10, y: 10
            width: 140, height: 90
            fill: Color.RED
        },
        SwingLabel {
            translateX: 100 translateY: 100
            text: "Label"
        },
        SwingButton {
            translateX: 20 translateY: 120
            text: "Print"
            action: function() {
                // 印刷
                node.print();
            }
        }
    ]
};

var stage = Stage {
    title : "Printing Test"
    scene: Scene {
        width: 200
        height: 200
        content: node
    }
};