Solved

java.awt.print VS javax.print

Posted on 2004-04-16
9
2,379 Views
2 Endorsements
Last Modified: 2012-08-14
Hello everyone,

I have to create a class that will print out a document that has a barcode (graphic) in it. This document will be created in the code (don't know which type of object yet) and does not come from the HD (maybe this makes a difference, i don't know).

I've been reading about different ways to acheive this and found that there are many packages that offer printing possibilities.

My question is, what's the main difference between JAVA.AWT.PRINT and JAVAX.PRINT ? Which one would be best ?

Thanks
2
Comment
Question by:mariec
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 

Author Comment

by:mariec
ID: 10856981
Points increased.
0
 

Author Comment

by:mariec
ID: 10866911
since nobody seems to really know this, are there any examples of how to print some text with some images? Is it possible to format the elements on a page ?

0
 

Accepted Solution

by:
johnknapp earned 200 total points
ID: 10867304
Well, they are not really one or the other,

javax.print.* and it supplimentary packages are for printer communications, i.e. getting the available printers, querying printer functionality, and sending print jobs, listening to print jobs, among other things

java.awt.print is used for the print code The code that generates the printing

Here is how I usuall incorporate my printing (there is some extra stuff in here, but this is also a complicated topic)

i usually start out with a base class, just to supply basic printing params and gives me a canvas to draw on

public class AbstractPrintableDocument extends JComponent implements PrintableDocument {

    protected String documentName;

    public AbstractPrintableDocument() {
   
    }

    public DocPrintJob getPrintJob(PrintService ps) throws NullPointerException {
        return (ps.createPrintJob());
    }
   
    public PrintRequestAttributeSet getPrintRequestAttributeSet() {
        return (null);
    }
   
    public Doc getDoc() {
        return (null);
    }
   
    public void print(PrintService ps) throws PrintException {}

    public void addPrintJobListener(PrintJobListener l) {}
   
    public void removePrintJobListener(PrintJobListener l) {}    

    public int print(java.awt.Graphics graphics, java.awt.print.PageFormat pageFormat, int pageIndex) {
        return (NO_SUCH_PAGE);
    }

    public void setDocumentName(String documentName) {
        this.documentName = documentName;
    }

}

and then override that with something useful like ...

public class Cheshire2UpPrintableDocument extends AbstractPrintableDocument {

    private static final boolean debug = true;

    private Dimension dimension;

    private PrintRequestAttributeSet set;
   
    private Font defaultFont;
   
    private Doc doc;

    private int currentPage = 0;

    private PrintRecord[] records;

    private int totalPages = 0;

    private Paginator paginator;

    private boolean paginated = false;

    private String dateString;

    public Cheshire2UpPrintableDocument() {
        super();
        set = _getPrintRequestAttributeSet();
        doc = _getDoc();
        dateString = _getDateString();
        defaultFont = _getDefaultFont();
        dimension = new Dimension(612, 792);
        records = new PrintRecord[0];
        paginator = new Paginator(8);
    }
   
    private String _getDateString() {
        java.util.Date d = new java.util.Date(System.currentTimeMillis());
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("MM/dd/yyyy");
        String s = format.format(d);
        return (s);
    }

    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { // here is the java.awt.print.Printable implementation
        if (!paginated)
            paginate((Graphics2D) graphics);
        if (pageIndex < totalPages) {
            currentPage = pageIndex;
            status("Page Index At Print: " + pageIndex);
            paintComponent(graphics);
            return (PAGE_EXISTS);
        } else {
            return (NO_SUCH_PAGE);
        }
    }

    public PrintRequestAttributeSet getPrintRequestAttributeSet() { return (set); }

    protected PrintRequestAttributeSet _getPrintRequestAttributeSet() { // tells the printer what my document will require
        PrintRequestAttributeSet mset = new HashPrintRequestAttributeSet();
        mset.add(OrientationRequested.PORTRAIT);
        mset.add(new JobName((documentName != null ? documentName : "Cheshire 2 Up Document"), null));
        MediaPrintableArea area = new MediaPrintableArea(.5f, .5f, 7.5f, 10f, MediaPrintableArea.INCH);
        mset.add(area);
        return (mset);    
    }
   
    protected Doc _getDoc() {
        Doc mdoc = new SimpleDoc(this,
                                 DocFlavor.SERVICE_FORMATTED.PRINTABLE,
                                 null);
        return (mdoc);
    }

    public Doc getDoc() { return (_getDoc()); }

    protected Font _getDefaultFont() {
        javax.swing.JTextField field = new javax.swing.JTextField();
        Font font = field.getFont();
        font = font.deriveFont(Font.PLAIN, 10f); // 10's gotta work
        font = Font.getFont("Arial", font);
        font.deriveFont(Font.PLAIN, 10f);
        if (debug) System.out.println("Cheshire2UpPrintableDocument Default Font Is: " + font.getName());
        return (font);
    }

    public Dimension getMaximumSize() { return (dimension); }
   
    public Dimension getMinimumSize() { return (dimension); }
   
    public Dimension getPreferredSize() { return (dimension); }
   
    public void setPrintRecords(PrintRecord[] recs) { // sets the records this document will print
        records = new PrintRecord[recs.length];
        System.arraycopy(recs, 0, records, 0, records.length);
        if (debug) System.out.println(getClass().getName() + " setPrintRecords " + records.length);
    }
   
    public void setPrintRecords(ExportRecord[] exRecs) {
        Vector temp = new Vector();
        for (int i = 0; i < exRecs.length; i++) {
            temp.addElement(PrintRecord.derive(exRecs[i]));
        }
        Object[] arr = temp.toArray();
        PrintRecord[] recs = new PrintRecord[arr.length];
        System.arraycopy(arr, 0, recs, 0, arr.length);
        setPrintRecords(recs);
    }
   
    protected void paginate(Graphics2D g) {
        paginator.setRecords(records); // paginator is a utility class to split pages based off the number of records
        totalPages = paginator.getPages();
        paginated = true;
    }
   
    protected void paintComponent(Graphics g) { // overriden to paint the document
        super.paintComponent(g);
        paintDocument((Graphics2D) g);
    }
   
    protected void paintDocument(Graphics2D g) {
        paintBackground(g);

        status("finished painting background");

        status("start pagination");

        if (!paginated)
            paginate(g);

        status("finished pagination");

        g.setFont(defaultFont);

        g.translate(36, 36);
       
        status("finished translation");
       
        g.setColor(Color.black);
       
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                           RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
       
        status("getting records");
       
        Object[] temp = paginator.getRecordsByPage(currentPage);    
        PrintRecord[] recs = new PrintRecord[temp.length];
        System.arraycopy(temp, 0, recs, 0, recs.length);
       
        status("finished records");
       
        if (debug) System.out.println("From Paginator on page " + currentPage + " recs " + recs.length);
       
        int recPos = 0;
       
        status("starting to paint records");
       
        for (int rows = 0; rows < 4; rows++) {
            for (int cols = 0; cols < 2; cols++) {
                PrintRecord rec = (recPos < recs.length ? recs[recPos] : null);
                recPos++;
                paintRecord(g, rows, cols, rec);
            }
        }
       
        status("finished painting records");
       
       
    }
   
    private void status(String msg) {
        if (debug) {
            System.out.println(getClass().getName() + ": " + msg);
        }
    }
   
    protected void paintRecord(Graphics2D g, int row, int col, PrintRecord rec) {
        if (rec == null)
            return;
        if (debug) System.out.println("Printing Record " + row + " " + col);
        Point2D point = translate(row, col);
        status("paintRecordAt(" + row + ", " + col + ")");
        FontRenderContext frc = g.getFontRenderContext();
        TextLayout layout = null;
        String[] lines = prepareRecord(rec);
        float currentY = (float) point.getY();
        String ifNull = "ifNull";
        for (int i = 0; i < lines.length; i++) {
            if (lines[i] == null || lines[i].length() == 0) {
                layout = new TextLayout(ifNull, g.getFont(), frc);
                currentY += layout.getAscent();
                // layout.draw(g, (float) point.getX(), currentY);
                currentY += layout.getDescent() + layout.getLeading();
            } else {
                layout = new TextLayout(lines[i], g.getFont(), frc);
                currentY += layout.getAscent();
                layout.draw(g, (float) point.getX(), currentY);
                currentY += layout.getDescent() + layout.getLeading();
            }
        }
    }
   
    protected String[] prepareRecord(PrintRecord rec) {
        Vector temp = new Vector();
        String firstRec = "NAME RECORD";
        firstRec += " ";
        firstRec += dateString;
        temp.add(firstRec);
        temp.add(null);
        if (rec.getFullName() != null)
            temp.add(rec.getFullName());
        if (rec.getCompanyName() != null)
            temp.add(rec.getCompanyName());
        if (rec.getAddress() != null)
            temp.add(rec.getAddress());
        if (rec.getCity() != null && rec.getState() != null && rec.getZip() != null)
            temp.add(prepareCityStateZip(rec));
        temp.add(formatPhone("Business", rec.getPrimaryPhone()));
        temp.add(formatPhone("Home", rec.getSecondaryPhone()));
        String add1 = rec.getAdditional1();
        String add2 = rec.getAdditional2();
        if (add1 != null)
            temp.add(add1);
        if (add2 != null)
            temp.add(add2);
        temp.add(rec.getCode());
        Object[] arr = temp.toArray();
        String[] s = new String[arr.length];
        System.arraycopy(arr, 0, s, 0, s.length);
        return (s);
    }
   
    private String prepareCityStateZip(PrintRecord rec) {
        StringBuffer sb = new StringBuffer();
        sb.append(rec.getCity()).append(", ").append(rec.getState());
        sb.append(" ");
        sb.append(formatZip(rec.getZip()));
        return (sb.toString());
    }
   
    protected Point2D translate(int row, int col) {
        Point2D point = new Point2D.Float();
        switch (row) {
            case 0: point.setLocation(0, 13.0000/40.0000); break;
            case 1: point.setLocation(0, 108.0000/40.0000); break;
            case 2: point.setLocation(0, 203.0000/40.0000); break;
            case 3: point.setLocation(0, 298.0000/40.0000); break;
        }
        switch (col) {
            case 0: point.setLocation(24.0000/40.0000, point.getY()); break;
            case 1: point.setLocation(174.0000/40.0000, point.getY()); break;
        }
        Point2D act = new Point2D.Double((point.getX() * 72), (point.getY() * 72));
        status("Returning Point: " + act.getX() + ", " + act.getY());
        return (act);
    }

    private String formatPhone(String title, String phone) {
        if (phone == null || phone.length() == 0)
            return (title + ":");
        StringBuffer sb = new StringBuffer();
        char[] arr = phone.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            appendIfNumeric(sb, arr[i]);
        }
        String num = sb.toString();
        sb.setLength(0);
        sb.append(title);
        sb.append(": ");
        if (num.length() == 10) {
            sb.append("(");
            sb.append(num.substring(0, 3));
            sb.append(") ");
            sb.append(num.substring(3, 6));
            sb.append("-");
            sb.append(num.substring(6, 10));
        }
        return (sb.toString());
    }
   
    private String formatZip(String zip) {
        if (zip == null || zip.length() == 0)
            return ("");
        StringBuffer sb = new StringBuffer();
        char[] arr = zip.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            appendIfNumeric(sb, arr[i]);
        }
        zip = sb.toString();
        if (zip.length() == 9) {
            sb.setLength(0);
            sb.append(zip.substring(0, 5));
            sb.append("-");
            sb.append(zip.substring(5, zip.length()));
            return (sb.toString());
        } else {
            return (zip);
        }
       
    }

    private void appendIfNumeric(StringBuffer sb, char c) {
        switch (c) {
            case '0': sb.append(c); return;
            case '1': sb.append(c); return;
            case '2': sb.append(c); return;
            case '3': sb.append(c); return;
            case '4': sb.append(c); return;
            case '5': sb.append(c); return;
            case '6': sb.append(c); return;
            case '7': sb.append(c); return;
            case '8': sb.append(c); return;
            case '9': sb.append(c); return;
            default: return;
        }
    }

    protected void paintBackground(Graphics2D g) {
        Rectangle2D rect = new Rectangle2D.Float(0f, 0f, dimension.width, dimension.height);
        g.setColor(Color.white);
        g.fill(rect);
    }
   
}

Anyway, sorry about verboseness the document prints 8 address records 4 * 2 4 rows, 2 columns

The code which is prints this document is fairly simple The complexity is kept in the printable document

    protected void printData() {
        final Cheshire2UpPrintableDocument dbs = new Cheshire2UpPrintableDocument();
        dbs.setPrintRecords(records); // obtained in another part of the code
        final PrinterJob job = PrinterJob.getPrinterJob(); // gets a printer job to create a print dialog
        boolean res = job.printDialog(dbs.getPrintRequestAttributeSet());  // returns true if user said yes to printing
        if (res) {
            job.setPrintable(dbs);
            final PrintService ps = job.getPrintService(); // gets the users chosen printer
            Runnable r = new Runnable() {
                public void run() { // always run print code in sep thread, since it is generally pretty time consuming
                    try {
                        DocPrintJob jarb = ps.createPrintJob();
                        jarb.print(dbs.getDoc(), dbs.getPrintRequestAttributeSet());
                    } catch (Exception e) {
                        showExceptionSafely(e);
                    }
                }
            };
            Thread t = new Thread(r);
            t.start();
        } else {
       
        }    
    }

So, the java.awt.print.* package is still generally the workhorse responisble for actual formatting and printing

while the javax.print.* packages are used to get the print data to the correct printer with the correct parameters.

Hope This Helps,
John
0
MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

 

Author Comment

by:mariec
ID: 10867754
Thanks, this looks like what i needed.

Is the PrintableDocument interface from the com.davidflanagan.examples.print package? If not, does is implement Pageable and Printable anyway?
0
 

Assisted Solution

by:johnknapp
johnknapp earned 200 total points
ID: 10869446
Sorry, I should have posted that also:

It isn't from the com.davidflanagan.examples.print package, but the idea of it was taken from that among other sources . . . here is the code for PrintableDocument

package com.asymm.listman.shared;

import java.awt.print.Printable;

import javax.print.PrintService;
import javax.print.DocPrintJob;
import javax.print.Doc;
import javax.print.PrintException;

import javax.print.attribute.PrintRequestAttributeSet;

import javax.print.event.PrintJobListener;

public interface PrintableDocument extends Printable  {

    /**
     * Gets a doc print job to print with the appropriate parameters set
     * @param ps The print service to print the job to
     * @return A doc print job object to print
     * @exception java.lang.NullPointerException if print service parameter is null
     */
    public DocPrintJob getPrintJob(PrintService ps) throws NullPointerException;

    /**
     * Gets the print request attribute set that this printable document will use
     * @return A print request attribute set with appropriate parameters set
     */
    public PrintRequestAttributeSet getPrintRequestAttributeSet();

    /**
     * Get doc that this will use internally
     * @return The doc
     */
    public Doc getDoc();    

    /**
     * Handles all printing for this document
     * @param ps The print service to print to
     * @exception javax.print.PrintException If an underlying print exception occurs
     */
    public void print(PrintService ps) throws PrintException;    

    public void addPrintJobListener(PrintJobListener l);
   
    public void removePrintJobListener(PrintJobListener l);

    public void setDocumentName(String documentName);

}

Sorry about not posting that again,

It has been a while since I went that deep into it again, I ususally just extend AbstractPrintableDocument for the stuff since for this current project with some 20+ printables and another 7 faxables I am trying to cut down on my work as much as possible.

0
 

Assisted Solution

by:johnknapp
johnknapp earned 200 total points
ID: 10869517
Also, sorry I forgot about printing images . . . but this is esentially how I do it

    /**
     * Draws the logo
     * @param g The graphics 2d object to draw on
     * @see #drawSalesOrder
     */
    protected void drawLogo(Graphics2D g) {
        status("drawLogo(Graphics2D)");
        BufferedImage li = getLogoImage();
        if (li == null) {
               
        } else {
            g.scale(.125, .125);
            g.drawImage(li, null, 0, 0);
            g.scale(8, 8);
            ypos = li.getHeight();
        }
    }

    /** Gets the logo image specified in the logoFile */
    private BufferedImage getLogoImage() {
        BufferedImage logoImage = null;
        try {
            logoImage = ImageIO.read(logoFile);
            if (debug) System.out.println("Successfully Read in Image File");
        } catch (Exception e) {
            if (debug) System.out.println(e);
        }
        return (logoImage);
    }

The reason I scale down first by 8 is that the image is 8 times the size I want it to be . . . I did this since when I printed the normal size image at the 72 pixels / inch it printed kind of poor - some banding on the image, my printer prints at a higher res so I sized up the image so that there are more pixels per inch and it looks great.  Just remember to scale back to normal, since setting the scale on graphics will continue to keep it that scale until set to something else.

I hope that also helps.  Generally for my complicated printables they get pretty long 1000+ lines of code . . .

You can also look into generating from apache fop . . . to create adobe acrobat documents and print those after they are created.  This can help if you will eventually be faxing the same printables, or emailing pdfs.
0
 

Expert Comment

by:johnknapp
ID: 10869533
By The By,

where did you get the info on the bar code stuff, which bar code is it? I have a client in which I had to use a third party software package for bar coding . . . I couldn't find the open standards, except for the really simple barcodes . . .
0
 

Expert Comment

by:johnknapp
ID: 10869665
Oh and I also forgot,

If you want to print without user intervention and send the stuff to a chosen printer directly, you can bypass the whole print dialog with code similar to the following

Cheshire2UpPrintableDocument cheshDoc = new Cheshire2UpPrintableDocument(); // pretend already initialized

PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);

/*
 * I have a client properties thing where I keep a default printer stored, and then get the correct print service this way
 */
String dpName = ClientProperties.getString("defaultprinter", null); // gets the value specified by key defaultprinter, with null as a backup value if not found
PrintService defaultPrintService = null;
if (dpName == null) {
    // tell client no dp printer chosen
    return;
} else {
    for (int i = 0; i < services.length; i++) {
        if (serivces[i].getName().equals(dpName))
            defaultPrinterService = services[i];
    }
}

if (defaultPrinterService == null) {
    // warn user could not find default printer -maybe disconnected ? or name changed? have them rechoose
    return;
}

try {
    cheshDoc.print(defaultPrinterService); // or whichever one matches the criteria
} catch (Exception e) {
    // handle print exception
}
0
 

Author Comment

by:mariec
ID: 10870320
I doubled points because this is very helpful and more than I was expecting!


The barcode stuff comes from a third party package (ww.java4less.com) that our client gave us for developing their solution. Usually it is distributed as a package but they got the source code and in it is says that it can be modified for our needs. There are many standards included.
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
What's wrong with this code? 4 46
Eclipse Help Java EE 5,6,7 Documentation, why not Java EE 8 8 70
java mysql insert application 14 68
Read CLOB data from Oracle using JAVA 3 40
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
The viewer will learn how to implement Singleton Design Pattern in Java.
Suggested Courses

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question