Javaにおけるプリンタの検索と選択

プリンタの選択

GUIでプリンタを選択するには、印刷ダイアログを使います。

このダイアログを出して選択させるのは、PrinterJob#printDialog()か、ServiceUI.printDialog()のどちらかです。

PrinterJob#printDialog()では、選択の候補となるプリンタ群は自動的に接続されている全部のプリンタになります。

ServiceUI.printDialog()を使うときには候補の配列を引数にします。この配列は、予めlookupPrintServices()などで取得しておく必要があります。この時、用紙の大きさや両面印刷など、ある条件をつけることがあります。候補の取得はプリンタの選択とは別の概念になります。候補の中から選び出す作業を「選択」として、候補の取得はプリンタの「検索」と言っていいでしょう。

プリンタの検索

Javaにおいてプログラムの中からのプリンタの検索の方法は次の表のとおり3つです。(1)は選択も込みです。

方法 説明
(1) 印刷ダイアログ(PrinterJob#printDialog()) ダイアログを出せば検索は済んでいて、これだけで選択できる。ただしGUIで手動で選択するのみ。
(2) PrinterJob.lookupPrintServices() コンピュータに設定されているプリンタを検索する。選択は別。Windowsではプリンタ以外のデバイスも含まれる。
(3) PrintServiceLookup.lookupPrintServices() 引数に示す条件にあったプリンタを検索する(はず)。選択は別

(1).印刷ダイアログ

印刷ダイアログはPrinterJobクラスのメソッドです。プログラム実行中にマウスで選択します。プリンタの一覧はダイアログの中にしかありませんから、手動選択しかありません。自動で選択させることができません。

PrinterSelect01.java
import java.awt.print.*;
import javax.print.*;

public class PrinterSelect01{
   public static void main(String[] args) {
        PrinterJob pj = PrinterJob.getPrinterJob();
        if (pj.printDialog()) {
            PrintService sv = pj.getPrintService();
            System.out.println(sv.getName());
        }
    }
}

実行結果

printDialogで選択した結果はPrinterJobのインスタンスに設定されます。それをgetPrintService()で取り出してgetName()で文字列にして表示しています。

adachi@debian64:~$ java PrinterSelect01
Canon_MP493_series

(2).PrinterJobのlookup

Java1.4の拡張でPrinterJobクラスに追加されたlookupPrintServices()というstaticメソッドを使うものです。メソッドの戻値は使用できるサービス(プリンタ)の配列です。ダイアログを出さずにプリンタを決めることもできますが、メソッドに引数がないですから、コンピュータに設定されているすべてのプリンタが含まれます。

自動で選択するには得られたプリンタの一覧からなんらかの情報を得なければ選択のしようがありません。特にWindowsではプリンタ以外のデバイスも含まれる(サービスですから正当です)ので厄介です。得られた配列を使ってダイアログを作ることもできますが、それでは1の印刷ダイアログで選択するのと同じですから、わざわざこれを使う必要はありません。

このプログラムでは、配列の最後のプリンタを使うことにしています。

PrinterSelect02.java
import java.awt.print.*;
import javax.print.*;

public class PrinterSelect02{
   public static void main(String[] args) {
        PrinterJob pj = PrinterJob.getPrinterJob();
        PrintService defaultprn = pj.getPrintService();
        System.out.println(defaultprn.getName());
        System.out.println("---");
        PrintService[] svs = pj.lookupPrintServices();
        for(PrintService sv:svs){
            System.out.println(sv.getName());
        }
        try{
            pj.setPrintService(svs[svs.length-1]);
        }catch (PrinterException e) {
                System.err.println(e);
        }
        System.out.println("---");
        PrintService autoselectedprn = pj.getPrintService();
        System.out.println(autoselectedprn.getName());
    }
}

実行結果

まずデフォルトでPrinterJobのインスタンスに貼り付けられているプリンタ名を表示して、

lookupPrintServices()ですべてのプリンタを配列にしたものを受け取り、プリンタ名を列挙します。

setPrintService()で配列の最後のサービスをPrinterJobのインスタンスに設定します。

この作業には例外処理を描く必要があります。

最後にそれをgetPrintService()で取り出してgetName()で文字列にして表示しています。

adachi@debian64:~$ java PrinterSelect02
Canon_MP493_A4
---
Canon_MP493_A4
Canon_MP493_chou3
Canon_MP493_hagaki
Canon_MP493_hagaki_fuchinashi
Canon_MP493_series
Canon_MP493_you2
EPSON_EPSON_PX-1700F
---
EPSON_EPSON_PX-1700F

Canon_MP493_...がたくさんあるのは、同一のプリンタに異なるデフォルトの用紙を設定したものを別プリンタとして登録しているからです。Linux+Javaではトレイの切り替えがうまく働かないので、その対策です。

(3).PrintServiceLookupクラス

PrintServiceLookupクラスのlookupPrintServices()というstaticメソッドを使うものです。このメソッドは名前は2と同じですがクラスが違います。PrintRequestAttributeSetと、印刷データの種類を表すDocFlavorを引数をとり、それらを扱うことができるプリンタの一覧を得ることができるとAPI仕様に書いてあります。

条件に合致するプリンタの配列を受け取って、ServiceUI.printDialog()で更に手動選択します。

PrinterSelect03.java
import java.awt.print.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;

public class PrinterSelect03{
    public static void main(String[] args) {
        PrintRequestAttributeSet rqset = new HashPrintRequestAttributeSet();
        rqset.add(MediaSizeName.ISO_A3); 
        DocFlavor flv = DocFlavor.SERVICE_FORMATTED.PRINTABLE;

        PrintService[] svs = PrintServiceLookup.lookupPrintServices(flv,rqset);
        for(PrintService sv:svs){
            System.out.println(sv.getName());
        }
        PrintService service = ServiceUI.printDialog(
            null, 200, 200, svs, svs[0], flv, rqset);
        PrinterJob pj = PrinterJob.getPrinterJob();
        if (service != null) {
            try{
                pj.setPrintService(service);
            }catch (PrinterException e) {
                System.err.println(e);
            }
        }
        System.out.println("---");
        PrintService autoselectedprn = pj.getPrintService();
        System.out.println(autoselectedprn.getName());
    }
}

実行結果です

AttributeSetにA3を指定し、DocFlavorにDocFlavor.SERVICE_FORMATTED.PRINTABLEを指定してこの条件でプリンタを検索しています。

結果の配列を元にServiceUI.printDialog()で選択するようにします。

setPrintService()で、そのプリンタをPrinterJobのインスタンスに設定します。

この作業には例外処理を描く必要があります。

最後にそれをgetPrintService()で取り出してgetName()で文字列にして表示しています。

Linuxではこの条件の検索がしっかり働き、A3対応プリンタだけ選び出されます。

adachi@debian64:~$ java PrinterSelect03
EPSON_EPSON_PX-1700F
---
EPSON_EPSON_PX-1700F

プリンタ名で指定

PrinterSelect04.java
import java.awt.print.*;
import javax.print.*;

public class PrinterSelect04{
   public static void main(String[] args) {
        PrinterJob pj = PrinterJob.getPrinterJob();
        PrintService defaultprn = pj.getPrintService();
        System.out.println(defaultprn.getName());
        System.out.println("---");
        PrintService[] svs = pj.lookupPrintServices();
        PrintService foundprn = null;
        for(PrintService sv:svs){
            System.out.println(sv.getName());
            if(sv.getName().contains("Canon_MP493_series")) foundprn=sv;
        }
        if(foundprn!=null){
            try{
                pj.setPrintService(foundprn);
            }catch (PrinterException e) {
                    System.err.println(e);
            }
        }
        System.out.println("---");
        PrintService autoselectedprn = pj.getPrintService();
        System.out.println(autoselectedprn.getName());
    }
}

実行結果

PrinterSelect02.javaから改変した関係もあってプリンタの一覧を書き出していますが、黙って設定することも可能です。

もし、この名前のプリンタがなければ、デフォルトのままになります。

指定すべきプリンタの名前は、あらかじめコンピュータごとに調べておきます。

adachi@debian64:~$ java PrinterSelect04
Canon_MP493_A4
---
Canon_MP493_A4
Canon_MP493_chou3
Canon_MP493_hagaki
Canon_MP493_hagaki_fuchinashi
Canon_MP493_series
Canon_MP493_you2
EPSON_EPSON_PX-1700F
---
Canon_MP493_series