alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * PrintText.java - Short Description
 * Copyright (C) 1999 Scot Bellamy, ACTS, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.jext.print;

import java.util.*;
import java.awt.print.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import javax.swing.text.*;


/**
 * A simple printing class to handle basic text printing.
 * Accepts an array of Strings or a PlainDocument and
 * prints all the lines contained there in.  Each String
 * in the array is assumed to be a separate line.
*/
public class PrintText
{

  private int numberOfpages_ = 0; // The number of pages
  private Book pages_ = new Book(); // This holds each page
  private int wrapOffset_ = 0; // Used to determine where to begin a wrapped line.
  private String docTitle_; // Used for document title (i.e. file name) when including the page header
  private String[] text_; // Text to print.
  private PrintingOptions printOptions_; // Print options (i.e. font, print header, etc.)
  private boolean softTabs_ = true; // Indicates whether soft or hard tabs are used.
  private int tabSize_ = 4; // Tab stop if hard tabs are used.

  /**
   * Constructor - Accepts a plain document and uses default font.
   * No header information will be printed.
  */
  public PrintText(PlainDocument document)
  {
    this(document, "", new PrintingOptions(), false, 4);
  }

  /**
   * Constructor - Accepts a plain document as well as  other print options,
   * including font, page title, and header indicator (true if printing header, false otherwise).
  */
  public PrintText(PlainDocument document, String docTitle, PrintingOptions printOptions, boolean softTabs, int tabSize)
  {
    printOptions_ = printOptions;
    softTabs_ = softTabs;
    tabSize_ = tabSize;

    if (docTitle != null)
    {
      docTitle_ = docTitle;
    } else {
      // If a new doc and no title, set docTitle to "New Document"
      docTitle_ = "New Document";
    }

    //  Get Root element of the document
    Element root = document.getDefaultRootElement();

    //get the number of lines (i.e. child elements)
    int count = root.getElementCount();

    //Allocate the array
    String lines[] = new String[count];

    Segment segment = new Segment();

    // Get each line element, get its text and put it in the string array
    for (int i = 0; i < count; i++)
    {
      Element lineElement = (Element) root.getElement(i);
      try
      {
        document.getText(lineElement.getStartOffset(), lineElement.getEndOffset() - lineElement.getStartOffset(),
                segment);
        lines[i] = segment.toString();
      }
      catch (BadLocationException ble)
      {
      } // Nothing gets added to the Array if there is a bad location
    }
    text_ = lines;
    printTextArray();
  }


  /**
   * Constructor - accepts an array of Strings, uses the default font, no header.
  */
  PrintText(String[] text)
  {
    printOptions_ = new PrintingOptions();
    text_ = text;
    printTextArray();
  }

  /**
   * Constructor - accepts an array of Strings and a font, no header.
  */
  PrintText(String[] text, Font font)
  {
    printOptions_ = new PrintingOptions();
    text_ = text;
    printTextArray();
  }


  /**
   * Where the print processing begins.
  */
  void printTextArray()
  {
    PageFormat pgfmt = printOptions_.getPageFormat();
    Font pageFont = printOptions_.getPageFont();
    try
    {
      PrinterJob job = PrinterJob.getPrinterJob(); // create a printjob
      //            pgfmt = job.pageDialog(pgfmt);                  // set a page format. Comment this if you do not want this to show
      //            pgfmt = job.validatePage(pgfmt);                // make sure the pageformat is ok

      text_ = removeEOLChar();

      if (printOptions_.getPrintLineNumbers() == true)
      {
        text_ = addLineNumbers();
      }
      if (printOptions_.getWrapText() == true)
      {
        text_ = wrapText();
      }

      pages_ = pageinateText(); // do the pagination

      try
      {
        job.setPageable(pages_); // set the book pageable so the printjob knows we are printing more than one page (maybe)
        if (job.printDialog())
        {
          job.print(); // print.  This calls each Page object's print method
        }
      }

      // catch any errors and be as ambiguous about them as possible :)
      catch (Exception e)
      {
        JOptionPane.showMessageDialog(null, "Printer Error", "Error", JOptionPane.OK_OPTION);
      }
    }
    catch (Exception e)
    {
      JOptionPane.showMessageDialog(null, "Printer Error", "Error", JOptionPane.OK_OPTION);
    }
  }

  /**
   * Eliminates end of line characters
  */
  private String[] removeEOLChar()
  {
    String temp1, temp2, temp3;
    int lineCount = text_.length;
    String [] newText = new String[lineCount];
    int offset = 0;

    for (int i = 0; i < lineCount; i++)
    {
      if (text_[i].length() == 1)
      {
        newText[i] = " ";
      }
      else
      {
        temp1 = text_[i].substring(text_[i].length() - 2, text_[i].length() - 1);
        temp2 = text_[i].substring(text_[i].length() - 1, text_[i].length());
        if (temp1.compareTo("\r") == 0 || temp1.compareTo("\n") == 0)
        {
          offset = 2;
        }
        else if (temp2.compareTo("\r") == 0 || temp2.compareTo("\n") == 0)
        {
          offset = 1;
        }
        else
        {
          offset = 0;
        }
        temp3 = text_[i].substring(0, text_[i].length() - offset);

        // Process tabs.  Assume tab stops.
        StringBuffer temp4 = new StringBuffer();
        int length = temp3.length();
        for (int j = 0; j < length; j++)
        {
          if ("\t".equals(temp3.substring(j, j + 1)) == true)
          {
            // Calcualte the numbe of spaces to the tab stop.
            int numSpaces = (temp4.length()) % tabSize_;

            if (numSpaces == 0)
            {
              numSpaces = tabSize_;
            }
            for (int x = 0; x < numSpaces; x++)
            {
              temp4.append(" ");
            }
          }
          else
          {
            temp4.append(temp3.substring(j, j + 1));
          }
        }
        newText[i] = temp4.toString();
      }
    }
    return newText;
  }



  /**
   * Addes line numbers to the beginning of each line.
  */
  private String[] addLineNumbers()
  {
    int numLines = text_.length;
    int totalNumSpaces = 0;
    String temp;
    String [] newText = new String[numLines];


    // Get the total number of digits in last line number
    // So that spacing and alignment can be done properly.
    Integer lines = new Integer(numLines);
    temp = lines.toString();
    totalNumSpaces = temp.length();

    // Set the wrap offset so that we can start wrapped lines in the proper place.
    wrapOffset_ = totalNumSpaces + 3;


    for (int i = 0; i < numLines; i++)
    {
      StringBuffer num = new StringBuffer();
      num.append(i + 1);
      int numLen = num.length();

      StringBuffer lineNum = new StringBuffer();

      for (int j = 0; j < (totalNumSpaces - numLen); j++)
      {
        lineNum.append(' ');
      }
      lineNum.append(num.toString());

      newText[i] = lineNum.toString() + ".  " + text_[i];
    }

    return newText;

  }

  /**
   * Creates a new array of lines that all fit the width of the page.
  */
  private String[] wrapText()
  {
    String currentLine = null;
    String tempString = null;
    Vector temp = new Vector();
    int lineCount = text_.length;
    int newLineCount = 0;
    StringBuffer wrapSpaces = new StringBuffer("");
    int i = 0;
    PageFormat pgfmt = printOptions_.getPageFormat();
    Font pageFont = printOptions_.getPageFont();
    double pageWidth = pgfmt.getImageableWidth();

    for (i = 0; i < wrapOffset_; i++)
    {
      wrapSpaces.append(' ');
    }

    for (i = 0; i < lineCount; i++)
    {
      currentLine = text_[i];
      while (pageFont.getStringBounds(currentLine,
              new FontRenderContext(pageFont.getTransform(), false, false)).getWidth() > pageWidth)
      {
        int numChars = (int)(currentLine.length() * pageWidth / pageFont.getStringBounds(currentLine,
                new FontRenderContext(pageFont.getTransform(), false, false)).getWidth());
        temp.add(currentLine.substring(0, numChars));
        currentLine = wrapSpaces.toString() + currentLine.substring(numChars, currentLine.length());
      }
      temp.add(currentLine);
    }

    newLineCount = temp.size();
    String [] newText = new String[newLineCount];

    for (int j = 0; j < newLineCount; j++)
    {
      newText[j] = (String) temp.get(j);
    }


    return newText;

  }



  /**
   * The pagination method, Paginate the text onto Printable page objects
  */
  private Book pageinateText()
  {

    Book book = new Book();
    int linesPerPage = 0; // lines on one page
    int currentLine = 0; // line I am  currently reading
    int pageNum = 0; // page #
    PageFormat pgfmt = printOptions_.getPageFormat();
    Font pageFont = printOptions_.getPageFont();
    int height = (int) pgfmt.getImageableHeight(); // height of a page
    int pages = 0; // number of pages

    linesPerPage = height / (pageFont.getSize() + 2); // number of lines on a page
    pages = ((int) text_.length / linesPerPage); // set number of pages
    String[] pageText; // one page of text
    String readString; // a temporary string to read from master string

    convertUnprintables(); // method to keep out errors

    if (printOptions_.getPrintHeader() == true)
    {
      linesPerPage = linesPerPage - 2;
    }

    while (pageNum <= pages)
    {

      pageText = new String[linesPerPage]; // create a new page
      for (int x = 0; x < linesPerPage; x++)
      {
        try
        {
          readString = text_[currentLine]; // read the string
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
          readString = " ";
        }
        pageText[x] = readString; // add to the page

        currentLine++;
      }
      pageNum++; // increase the page number I am on
      book.append(new Page(pageText, pageNum), pgfmt); // create a new page object with the text and add it to the book

    }
    return book; // return the completed book

  }

  /**
   * Converts unprintable things to a space.  stops some errors.
  */
  private void convertUnprintables()
  {
    String tempString;
    int i = text_.length;
    while (i > 0)
    {
      i--;
      tempString = text_[i];
      if (tempString == null || "".equals(tempString))
      {
        text_[i] = " ";
      }
    }
  }

  /**
   * An inner class that defines one page of text based
   * on data about the PageFormat etc. from the book defined
   * in the parent class
  */
  class Page implements Printable
  {

    private String[] pageText_; // the text for the page
    private int pageNumber_ = 0;

    Page(String[] text, int pageNum)
    {
      this.pageText_ = text; // set the page's text
      this.pageNumber_ = pageNum; // set page number.
    }

    /**
     * Defines the Printable print method, for printing a Page
    */
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException // the printing part

    {
      int pos;
      int posOffset = 1;
      double pageWidth = pageFormat.getImageableWidth();
      Font pageFont = printOptions_.getPageFont();

      if (printOptions_.getPrintHeader() == true)
      {
        StringBuffer header = new StringBuffer();
        StringBuffer pageNumText = new StringBuffer();
        int i = 0;
        int headerPos = 0;
        int numSpaces = 0;

        Calendar date = Calendar.getInstance();
        header.append(date.get(Calendar.DAY_OF_MONTH));
        header.append('/');
        header.append(date.get(Calendar.MONTH) + 1);
        header.append('/');
        header.append(date.get(Calendar.YEAR));

        pageNumText.append("Page ");
        pageNumText.append(pageNumber_);

        int xPos;
        double margin = (pageFormat.getWidth() - pageFormat.getImageableWidth()) / 2;
        graphics.setFont(printOptions_.getHeaderFont());
        graphics.setColor(Color.black);
        pos = (int) pageFormat.getImageableY() + (printOptions_.getHeaderFont().getSize() + 2);
        graphics.drawString(header.toString(), (int) pageFormat.getImageableX(), pos); // draw a line of text
        xPos = (int)((pageFormat.getWidth() / 2) - (graphics.getFontMetrics().stringWidth(docTitle_) / 2));
        graphics.drawString(docTitle_, xPos, pos);
        xPos = (int)(pageFormat.getWidth() - margin - graphics.getFontMetrics().stringWidth(pageNumText.toString()));
        graphics.drawString(pageNumText.toString(), xPos, pos);
        posOffset = 3;
      }

      graphics.setFont(pageFont); // Set the font
      graphics.setColor(Color.black); // set color

      for (int x = 0; x < (pageText_.length); x++)
      {
        pos = (int) pageFormat.getImageableY() + (pageFont.getSize() + 2) * (x + posOffset);
        graphics.drawString(this.pageText_[x], (int) pageFormat.getImageableX(), pos); // draw a line of text
      }

      return Printable.PAGE_EXISTS; // print the page
    }

  }

  /**
   * An inner class that defines one section of printable text.
   * This allows the flexability to assign different fonts to
   * individual words or phrases (i.e. for headers/footers or
   * Syntax highlighting (pretty print).
  */
  class PrintableText
  {
    private Font font_;
    private boolean newLine_ = true;
    private String text_;

    PrintableText()
    {
    }

    PrintableText(String text, Font font, boolean newLine)
    {
      text_ = text;
      font_ = font;
      newLine_ = newLine;
    }

    String getText()
    {
      return text_;
    }

    void setText(String text)
    {
      text_ = text;
    }

    Font getFont()
    {
      return font_;
    }

    void setFont(Font font)
    {
      font_ = font;
    }

    boolean isNewLine()
    {
      return newLine_;
    }

    void setNewLine(boolean newLine)
    {
      newLine_ = newLine;
    }
  }
}

// End of PrintText.java
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.