PR
TextCompPrintSample1
図1 TextCompPrintSample1

Javaで実装するのが面倒なものの一つに印刷があります。

慣れてしまえばどうということはないのですが,印刷に特有の知識が必要になるので,なかなか手が出ません。

そこで,印刷の知識がなくても簡単に印刷を実現できる機能がJ2SE 5.0から徐々に取り入れられてきています。J2SE 5.0ではJTableクラスに簡易印刷機能が導入されました。

Java SE 6では,JTextAreaクラスやJEditorPaneクラスなど文字列を扱うテキスト・コンポーネントに簡易印刷機能が導入されました。

今週はこの簡易印刷機能を試してみましょう。

簡易印刷機能は,JEditorPaneクラスなどの親クラスであるjavax.swing.text.JTextComponentクラスに導入されました。したがって,この機能を使用できるのは,JTextFieldクラス,JTextAreaクラス,JEditorPaneクラスの三つのクラスです。

使い方はJTableクラスの簡易印刷機能とほとんど同じです。

サンプルのソースコード TextCompPrintSample1.java

このサンプルはJEditorPaneクラスを使用して,自分自身のソースコードを表示します(図1)。フレームの一番下には印刷ボタンがあり,クリックすると印刷を行います。

コンストラクタを以下に示します。

public TextCompPrintSample1()
            throws MalformedURLException, IOException {
    frame = new JFrame("Text Component Print Sample");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    File file = new File("TextCompPrintSample1.java");
    URL url = file.toURI().toURL();
    editorPane = new JEditorPane(url);

    frame.add(new JScrollPane(editorPane));

    JButton printButton = new JButton("印刷");
    printButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            try {
                // テキストコンポーネントの印刷
                editorPane.print();

            } catch (PrinterException ex) {
                JOptionPane.showMessageDialog(
                    frame, 
                    "印刷に失敗しました",
                    "印刷失敗",
                    JOptionPane.WARNING_MESSAGE);
            }
        }
    });
    frame.add(printButton, BorderLayout.SOUTH);

    frame.setSize(600, 700);
    frame.setVisible(true);
}
実行結果
図2 実行結果(PDF

JEditorPaneクラスの引数にドキュメントのURLを与えれば,自動的にドキュメントをロードしてくれます。この機能を使用してローカル・ファイルを読み込むこともできます。そのために,FileオブジェクトからURLオブジェクトを生成しています。URLオブジェクトに直接変換できないため,間にURIオブジェクトを挟んでいます。

JEditorPaneオブジェクトに表示された文字列の印刷は,printButtonのイベント処理で行います。印刷はとても簡単。赤字で示しているように,単にprintメソッドをコールするだけです。

印刷に失敗したら,ダイアログを表示します。

実行してPDFを作成してみたのが図2です。何の飾りもない,素っ気ない出力になりました。

これではちょっと寂しいので,ヘッダーとフッターを付けてみましょう。

サンプルのソースコード TextCompPrintSample2.java

印刷処理以外の部分はTextCompPrintSample1クラスとほとんど変わらないので,印刷処理の部分だけを示します。

printButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        try {
            // テキスト・コンポーネントの印刷
            // ヘッダー,フッター付き
            editorPane.print(
                new MessageFormat(file.getName()),
                new MessageFormat("Page {0}"));
        } catch (PrinterException ex) {
            JOptionPane.showMessageDialog(
                frame, 
                "印刷に失敗しました",
                "印刷失敗",
                JOptionPane.WARNING_MESSAGE);
        }
    }
});
実行結果
図3 実行結果(PDF

TextCompPrintSample1クラスでは引数のないprintメソッドをコールしていましたが,ここでは引数があります。

第1引数がヘッダー,第2引数がフッターです。両方とも型はjava.text.MessageFormatクラスです。

MessageFormatクラスを使っているのは,ページ数を埋め込むためです。このコードではフッターにページ数が印刷されるようにしてみました。{0}の部分がページ数に置き換えられます。

印刷してみた結果が図3です。

若干ヘッダーのフォントサイズが大きいような気もしますが…。

残念ながら,ヘッダーやフッターのフォント・サイズや表示位置は固定です。

printメソッドにはオーバロードされたメソッドがもう一つあります。このメソッドでは,印刷部数や紙の大きさ,向きなどを指定できます。

とはいうものの,この印刷機能はあくまでも簡易的なものです。ヘッダーやフォント・サイズを変えられませんし,総ページ数を印刷することもできません。また,他のコンポーネントを一緒に印刷することもできません。

このような印刷を行うのであれば,従来通りの印刷処理を記述しなければなりません。

だからといって,簡易印刷機能が役に立たないというわけではありません。

今までは,テキスト・ファイルの内容を印刷だけでも,フレーバーや属性などの設定を行わなければなりませんでした。JEditorPaneクラスを使えば,フレーバーを全く気にすることなく,あっという間に印刷処理を作れます。

とりあえず印刷するだけ,ということであれば,簡易印刷機能で十分な場面は多いのではないでしょうか。

著者紹介 櫻庭祐一

横河電機 ネットワーク開発センタ所属。Java in the Box 主筆

今月の櫻庭

この時期,気になるのは何といってもJavaOne。年に1回,Javaの最大のお祭りです。

今年は5月8日から11日。ゴールデンウィークの直後にサンフランシスコのモスコニセンターで開催されます。

今年はどんなサプライズが飛び出すのでしょうか。Java SE 7はどうなるのか,Java EE 6は。JRubyをはじめとするスクリプトも気になるところ。今から,ワクワクドキドキなのです。