Java Language Listening print job request status change


Example

For the most printing clients, is extremely useful to know if a print job has finished or failed.

The Java Print Service API provide some functionalities to get informed about these scenarios. All we have to do is:

  • provide an implementation for PrintJobListener interface and
  • register this implementation at the print job.

When the print job state changes, we will be notified. We can do anything is needed, for example:

  • update a user interface,
  • start another business process,
  • record something in the database,
  • or simply log it.

In the example bellow, we will log every print job status change:

import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;

public class LoggerPrintJobListener implements PrintJobListener {

    // Your favorite Logger class goes here!
    private static final Logger LOG = Logger.getLogger(LoggerPrintJobListener.class);


    public void printDataTransferCompleted(PrintJobEvent pje) {
        LOG.info("Print data transfer completed ;) ");
    }

    public void printJobCompleted(PrintJobEvent pje) {
        LOG.info("Print job completed =) ");
    }

    public void printJobFailed(PrintJobEvent pje) {
        LOG.info("Print job failed =( ");
    }

    public void printJobCanceled(PrintJobEvent pje) {
        LOG.info("Print job canceled :| ");
    }

    public void printJobNoMoreEvents(PrintJobEvent pje) {
        LOG.info("No more events to the job ");
    }

    public void printJobRequiresAttention(PrintJobEvent pje) {
        LOG.info("Print job requires attention :O ");
    }
}

Finally, we can add our print job listener implementation on the print job before the print request itself, as follows:

DocPrintJob printJob = printService.createPrintJob();

printJob.addPrintJobListener(new LoggerPrintJobListener());

printJob.print(doc, pras);

The PrintJobEvent pje argument

Notice that every method has a PrintJobEvent pje argument. We don't use it in this example for simplicity purposes, but you can use it to explore the status. For example:

pje.getPrintJob().getAttributes();

Will return a PrintJobAttributeSet object instance and you can run them in a for-each way.


Another way to achieve the same goal

Another option to achieve the same goal is extending the PrintJobAdapter class, as the name says, is an adapter for PrintJobListener. Implementing the interface we compulsorily have to implement all of them. The advantage of this way it's we need to override only the methods we want. Let's see how it works:

import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobAdapter;

public class LoggerPrintJobAdapter extends PrintJobAdapter {

    // Your favorite Logger class goes here!
    private static final Logger LOG = Logger.getLogger(LoggerPrintJobAdapter.class);

    public void printJobCompleted(PrintJobEvent pje) {
        LOG.info("Print job completed =) ");
    }

    public void printJobFailed(PrintJobEvent pje) {
        LOG.info("Print job failed =( ");
    }
}

Notice that we override only some specific methods.

As the same way in the example implementing the interface PrintJobListener, we add the listener to the print job before sending it to print:

printJob.addPrintJobListener(new LoggerPrintJobAdapter());

printJob.print(doc, pras);