SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Java Graphicsを使ってかんたんプリント

JavaプログラムにAWTとJPSで印刷機能を実装する

  • X ポスト
  • このエントリーをはてなブックマークに追加

AWT Print

 AWT Printを使って印刷機能を実現する場合、Printableインタフェースの実装クラス作成が肝となります。まずは以下にサンプルコードを示します。

MyPrintable.javaの抜粋(Printable実装部分)
/**
* Printable,Pageableインターフェースの実装。
*/
public class MyPrintable implements Printable, Pageable{ //・・・省略・・・ public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { if (pageIndex < 2){ RoundDraw roundDraw = new RoundDraw(); //描画領域の設定 roundDraw.setWidth((int)pf.getImageableWidth()); roundDraw.setHeight((int)pf.getImageableHeight()); //余白を加味して平行移動 g.translate((int)pf.getImageableX(), (int)pf.getImageableY()); roundDraw.draw(g); //ページ番号の描画 g.drawString("Page:" + (pageIndex + 1), 20, 20); return Printable.PAGE_EXISTS; } else { return Printable.NO_SUCH_PAGE; } } //・・・省略・・・ }

 Printableインタフェースはprintメソッドを提供します。このメソッドは印刷実行時に後述のPrinterJobのprintメソッド内からコールバックの形で使用されます。

 引数で渡されるGraphicsを使用して描画を行うと、その内容が印刷物に出力されます。また、引数pageIndexには印刷しようとしているページのインデックスが(0から)セットされます。pageIndexの値を判断して、指示されたページの描画を行うことがprintメソッドの役割になります。

 呼び出し元には処理の成否を返す必要があります。pageIndexで指定されたページが存在し、正常に描画ができた場合にはPrintable.PAGE_EXISTSを、ページが存在しない場合にはPrintable.NO_SUCH_PAGEを戻り値に設定します。printメソッドはNO_SUCH_PAGEが返されるまで繰り返し呼び出されます。印刷ページの終了を判断してNO_SUCH_PAGEを返却する必要があります。今回のサンプルコードは3ページ目(pageIndexが2になった時)にNO_SUCH_PAGEとなるので2ページの印刷となります。

 なお、printメソッドはpageIndexを1ずつ増やしながら1回ずつ呼び出されるとは限らない点に注意してください。例えば「3ページ目を10枚」といった具合で、pageIndexに同じ値が設定されたまま繰り返し呼び出されることもあり得ます。印刷状況に関する情報をクラス変数などに留保せず、引数で与えられたpageIndexの値のみを判断基準として処理を行うようにしてください。

 ここでは最初のサンプルコードで登場したRoundDrawオブジェクトを使って描画処理を実装しています。プリンタで印刷する場合は余白についても考慮した方が良いでしょう。用紙内にきれいに収めるために、下図の要領で平行移動とサイズ指定を行います。

印刷用紙の余白
印刷用紙の余白

 印刷の処理の手順ですが、まずPrinterJobオブジェクトを取得します。これに先程のPrintableオブジェクトを設定します。最後にPrinterJobのprintメソッドを実行すると印刷が実行されます。

 PrinterJobオブジェクトは、印刷ジョブをあらわす抽象的なオブジェクトです。 getPrinterJob()で取得した時点では「どのプリンタに印刷するか?」「どのように印刷するか?」などの情報はまだ決定しておらず、抽象的な印刷ジョブとして生成されます。このジョブに対して、Printableを設定したり、印刷ダイアログから設定を行うことで明確な印刷ジョブの指定として完成されます。

AWTPrint .java
public class AWTPrint {
  public static void main(String[] args) 
        throws PrinterException {
    //PrintaerJobの取得
    PrinterJob job = PrinterJob.getPrinterJob();
    MyPrintable printable = new MyPrintable(job.defaultPage());
    //Printable, Pageableの設定
    job.setPrintable(printable);
    job.setPageable(printable);
    //印刷ダイアログの表示と印刷
    if (job.printDialog()){
      job.print();
    }
  }
}

 PrinterJobのprintDialogメソッドを実行すると、OS標準の印刷ダイアログが表示されます。printDialogメソッドは「OK」や「キャンセル」などのユーザ選択をboolean値で返します。printDialogメソッドがtrueを返却する時にだけ印刷を実行します。なお、AWT Printではダイアログを表示しなければ印刷オプション設定ができないという欠点があります。

 MyPrintableクラスではPageableインターフェースも実装しています。Pageableインターフェースは印刷物が何ページあるかといった情報を管理します。ページごとにPrintableオブジェクトを切り替えたりすることができます。

 今回のサンプルコードは、1つのPrintableオブジェクトが、ページ1、2の両方を印刷する実装になっています。全く異なるレイアウトを印刷する場合、例えば「1ページ目が表紙用のPrintableオブジェクト」「2ページ目以降が明細データのPrintableオブジェクト」のように、2つのPrintableオブジェクトを別々に作成し、getPrintableメソッドで対応するPritableオブジェクトを返却する構成にすることができます。

MyPrintable.javaの抜粋(Pageable装部分)
/**
* Printable,Pageableインターフェースの実装。
*/
public class MyPrintable implements Printable, Pageable{ private PageFormat pf; public MyPrintable(){ } public MyPrintable(PageFormat pf) { this.pf = pf; } public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { //・・・省略(前述したソースコード)・・・ } /**
* この印刷物の総ページ数を返却する。
* 印刷ダイアログでのページ数指定になる。
*/
public int getNumberOfPages() { return 2; //2ページあるとする } /**
* ページごとのページ書式を返却する。
* 今回のサンプルでは印刷ダイアログで指定したページ書式を
* 全ページで使用。
* 例えば、ページ1は縦置きでページ2は横置きなど、
* ページ書式の切り替えが実装できる。
*/
public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException { return pf; } /**
* ページごとのPritableを返却する。
* 例えば1ページ目の表紙用のPrintableと、
* 2ページ目以降の明細用のPrintableを切り替えたりすることができる。
*/
public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException { return this; } }

 実は、Pageableインターフェースがなくても印刷はできます。ただしその場合は、下図のようにダイアログの印刷範囲欄に表示されるページの値が適切に設定されません。

AWTPrintの印刷ダイアログ
AWTPrintの印刷ダイアログ

 印刷ダイアログのページ指定の最大値は、getNumberOfPagesメソッドで返される値になります。今回はPrintableオブジェクトが2ページの印刷を行うオブジェクトになっているので、固定値の2になっています。

 例えば、明細形式の印刷物で、全50明細、1ページあたりに20明細印刷するような場合は、50/20=2.5 となるのでページ数としては、getNumberOfPagesメソッドが3を返すような実装になります。

 さて、プログラムを実行してみましょう。印刷ダイアログが表示されるので、「OK」ボタンを押します。プリンタから紙面一杯に楕円が印刷されて出てくるはずです。

次のページ
JPS(Java Print Service)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

佐々木孝(ササキタカシ)

Javaをメインに業務システムの開発サポート、パッケージ開発、および技術研究をしています。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2468 2008/09/05 11:18

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング