2015-01-20 324 views
0

我正在開發一個打印文件的JAVA程序。 我需要知道當打印機完成打印文件,我發現這個簡單的代碼,這是有趣:如何知道打印機的打印方法何時完成打印文件?

import javax.print.*; 
import javax.print.attribute.DocAttributeSet; 
import javax.print.attribute.PrintServiceAttributeSet; 
import javax.print.attribute.standard.PrinterStateReason; 
import javax.print.attribute.standard.PrinterStateReasons; 
import javax.print.attribute.standard.Severity; 
import javax.print.event.*; 
import java.awt.*; 
import java.awt.print.PageFormat; 
import java.awt.print.Printable; 
import java.awt.print.PrinterException; 
import java.awt.print.PrinterJob; 
import java.io.*; 
import java.util.Set; 

/** 
* PrintTest 
*/ 
public class PrintTest implements PrintServiceAttributeListener,PrintJobListener,Doc, Printable, PrintJobAttributeListener { 

    private static final transient String TEXT = "12345"; 

    public static void main(String[] args) { 
    PrintTest test = new PrintTest(); 
    test.checkPrinters(); 
    } 

    public void checkPrinters() { 
    Thread newThread = new Thread(new Runnable() { 
     public void run() { 
    PrintService ps = PrinterJob.getPrinterJob().getPrintService(); 

    DocFlavor[] myFlavors = ps.getSupportedDocFlavors(); 
    ps.addPrintServiceAttributeListener(PrintTest.this); 
    DocPrintJob docJob = ps.createPrintJob(); 
     docJob.addPrintJobAttributeListener(PrintTest.this, null); 
    docJob.addPrintJobListener(PrintTest.this); 
    try { 
     docJob.print(PrintTest.this,null); 
    } 
    catch (PrintException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } 
    } }); 

    newThread.start(); 
    /** 
    PrintServiceAttributeSet attSet = ps.getAttributes(); 
    PrinterStateReasons psr = ps.getAttribute(PrinterStateReasons.class); 

    if (psr != null) { 
     Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT); 
     for (PrinterStateReason reason : errors) 
     System.out.printf(" Reason : %s",reason.getName()); 
     System.out.println(); 
    }   */ 
    } 

    public void attributeUpdate(PrintServiceAttributeEvent psae) { 
    System.out.println(psae.getAttributes()); 
    } 

    public void printDataTransferCompleted(PrintJobEvent pje) { 
    System.out.println("Transfer completed"); 
    } 

    public void printJobCompleted(PrintJobEvent pje) { 
    System.out.println("Completed"); 
    } 

    public void printJobFailed(PrintJobEvent pje) { 
    System.out.println("Failed"); 
    PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class); 
    if (psr != null) { 
     Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT); 
     for (PrinterStateReason reason : errors) 
     System.out.printf(" Reason : %s",reason.getName()); 
     System.out.println(); 
    } 
    } 

    public void printJobCanceled(PrintJobEvent pje) { 
    System.out.println("Canceled"); 
    } 

    public void printJobNoMoreEvents(PrintJobEvent pje) { 
    System.out.println("No more events"); 
    } 

    public void printJobRequiresAttention(PrintJobEvent pje) { 
    System.out.println("Job requires attention"); 
    PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class); 
    if (psr != null) { 
     Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT); 
     for (PrinterStateReason reason : errors) 
     System.out.printf(" Reason : %s",reason.getName()); 
     System.out.println(); 
    } 
    } 

    public DocFlavor getDocFlavor() { 
    return DocFlavor.SERVICE_FORMATTED.PRINTABLE; //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public Object getPrintData() throws IOException { 
    return this; 
    } 

    public DocAttributeSet getAttributes() { 
    return null; //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public Reader getReaderForText() throws IOException { 
    return null; //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public InputStream getStreamForBytes() throws IOException { 
    return null; //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { 
    return pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE; //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void attributeUpdate(PrintJobAttributeEvent pjae) { 
    System.out.println("Look out"); 
    } 
} 

所以,我感興趣的方法是這樣的:

public void printJobCompleted(PrintJobEvent pje) { 
    System.out.println("Completed"); 
    } 

但它不適合我。問題是打印機不支持這種類型的代碼。有人能告訴我一個支持這個代碼的打印機模型嗎?

+0

錯誤消息說什麼?你檢查了控制檯嗎? (我假設這是一個運行時錯誤,而不是編譯錯誤) – ochi 2015-01-20 20:08:22

+1

對於我來說,我不記得有任何應用程序(除了OS打印隊列管理器)在我的打印作業完成時通知我。所以我的猜測是,這很少,也許從未實現 – ControlAltDel 2015-01-20 20:18:47

+0

'printJobNoMoreEvents(PrintJobEvent pje)'調用以通知客戶端不會傳遞更多事件。產生此事件的一個原因是作業已成功完成,但打印系統的功能有限,無法驗證此事件。如果沒有其他終端事件(完成/失敗/取消)發送,則需要交付此事件。我認爲如果我們調用printJobNoMoreEvents(PrintJobEvent pje),我們可以假設我們的prit是成功的。 – 2017-05-01 02:44:49

回答

0

看示例代碼here

它看起來像你需要實現你的PrintJobAdapter。相關位是:

package com.your.package; 

import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import java.io.InputStream; 

import javax.print.Doc; 
import javax.print.DocFlavor; 
import javax.print.DocPrintJob; 
import javax.print.PrintService; 
import javax.print.PrintServiceLookup; 
import javax.print.SimpleDoc; 
import javax.print.event.PrintJobAdapter; 
import javax.print.event.PrintJobEvent; 

public class DetermineThatPrintJobHasFinished { 

    public static void main(String[] args) throws Exception { 
     //... see example in link 

     // Locate the default print service for this environment.  
     PrintService service = PrintServiceLookup.lookupDefaultPrintService(); 

     // Create and return a PrintJob capable of handling data from  
     // any of the supported document flavors.  
     DocPrintJob printJob = service.createPrintJob(); 

     // register a listener to get notified when the job is complete  
     JobCompleteMonitor monitor = new JobCompleteMonitor();  
     printJob.addPrintJobListener(monitor); 

     // Construct a SimpleDoc with the specified print data, doc flavor and doc attribute set.  
     Doc doc = new SimpleDoc(is, flavor, null); 

     // Print a document with the specified job attributes.  
     printJob.print(doc, null);  
     monitor.waitForJobCompletion(); 

     is.close(); 
    } 

    private static class JobCompleteMonitor extends PrintJobAdapter { 
     private boolean completed = false; 

     @Override 
     public void printJobCanceled(PrintJobEvent pje) { 
      signalCompletion(); 
     } 

     @Override 
     public void printJobCompleted(PrintJobEvent pje) { 
      signalCompletion(); 
     } 

     @Override 
     public void printJobFailed(PrintJobEvent pje) { 
      signalCompletion(); 
     } 

     @Override 
     public void printJobNoMoreEvents(PrintJobEvent pje) { 
      signalCompletion(); 
     } 

     private void signalCompletion() { 
      synchronized (JobCompleteMonitor.this) { 
       completed = true;  
       JobCompleteMonitor.this.notify();  
      } 
     } 

     public synchronized void waitForJobCompletion() {  
      try { 
       while (!completed) { 
        wait(); 
       } 
      } catch (InterruptedException e) { 
      } 
     } 
    } 
} 
+0

我試過你的代碼,但問題沒有解決。當我運行程序時,它將文件發送到打印機,然後終止。我需要程序等到打印機終止打印文件,然後程序必須調用PrintJobComplete方法 – user2062413 2015-01-21 09:46:06