Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 11/14/2003
*
* RPrintUtilities.java - A collection of static methods useful for printing
* text from Swing text components.
*
* This library is distributed under a modified BSD license. See the included
* LICENSE file for details.
*/
package org.fife.print;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.Segment;
import javax.swing.text.TabExpander;
import javax.swing.text.Utilities;
/**
* A collection of static methods useful for printing text from Swing text components.
*
* @author Robert Futrell
* @version 1.0
*/
public abstract class RPrintUtilities {
private static int currentDocLineNumber; // The line number in the document we are currently on.
private static int numDocLines; // The number of lines in the current document.
private static Element rootElement; // The first Element (line) in the current document.
// The characters at which to break a line if implementing word wrap.
private static final char [] BREAK_CHARS = { ' ', '\t', ',', '.', ';', '?', '!' };
// These variables are 'global' because RPrintTabExpander uses them.
/**
* The x-offset (for the page margin) when printing.
*/
private static int xOffset;
/**
* The length of a tab, in spaces.
*/
private static int tabSizeInSpaces;
/**
* The metrics of the font currently being used to print.
*/
private static FontMetrics fm;
/**
* Returns the position closest to, but before, position maxCharsPerLine in
* line of one of the chars in breakChars, or simply returns
* maxCharsPerLine-1 if none of the breakChars comes before
* that position. This position represents the logical line break for this java.lang.String
* if it is being printed in a monospaced font when lines can only be maxCharsPerLine
* characters long.
*
* @param line The text being printed.
* @param maxCharsPerLine Only up-to this many characters from
* line can be printed on one line.
* @return The logical position at which to stop printing line
* to simulate word wrap.
*/
private static int getLineBreakPoint(String line, final int maxCharsPerLine) {
int breakPoint = -1;
for (char breakChar : BREAK_CHARS) {
int breakCharPos = line.lastIndexOf(breakChar, maxCharsPerLine - 1);
if (breakCharPos > breakPoint) {
breakPoint = breakCharPos;
}
}
return (breakPoint==-1 ? maxCharsPerLine-1 : breakPoint);
}
/**
* Prints a Document using a monospaced font, and does no word wrapping (ie,
* words will wrap mid-word to the next line). This method is expected to be called from
* Printable 'print(Graphics g)' functions.
*
* @param g The graphics context to write to.
* @param doc The javax.swing.text.Document to print.
* @param fontSize the point size to use for the monospaced font.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to expand tabs to.
*
* @see #printDocumentMonospacedWordWrap
*/
public static int printDocumentMonospaced(Graphics g, Document doc, int fontSize, int pageIndex,
PageFormat pageFormat, int tabSize) {
g.setColor(Color.BLACK);
g.setFont(new Font("Monospaced", Font.PLAIN, fontSize));
// Initialize our static variables (these are used by our tab expander below).
tabSizeInSpaces = tabSize;
fm = g.getFontMetrics();
// Create our tab expander.
//RPrintTabExpander tabExpander = new RPrintTabExpander();
// Get width and height of characters in this monospaced font.
int fontWidth = fm.charWidth('w'); // Any character will do as font is monospaced.
int fontHeight = fm.getHeight();
int maxCharsPerLine = (int)pageFormat.getImageableWidth() / fontWidth;
int maxLinesPerPage = (int)pageFormat.getImageableHeight() / fontHeight;
final int startingLineNumber = maxLinesPerPage * pageIndex;
// The (x,y) coordinate to print at (in pixels, not characters).
// Since y is the baseline of where we'll start printing (not the top-left
// corner), we offset it by the font's ascent ( + 1 just for good measure).
xOffset = (int)pageFormat.getImageableX();
int y = (int)pageFormat.getImageableY() + fm.getAscent() + 1;
// A counter to keep track of the number of lines that WOULD HAVE been
// printed if we were printing all lines.
int numPrintedLines = 0;
// Keep going while there are more lines in the document.
currentDocLineNumber = 0; // The line number of the document we're currently on.
rootElement = doc.getDefaultRootElement(); // To shorten accesses in our loop.
numDocLines = rootElement.getElementCount(); // The number of lines in our document.
while (currentDocLineNumber -1) {
int spacesNeeded = tabSizeInSpaces - (tabIndex % tabSizeInSpaces);
StringBuilder stringBuilder = new StringBuilder();
for (int i=0; i maxCharsPerLine) {
numPrintedLines++;
if (numPrintedLines > startingLineNumber) {
g.drawString(curLineString.substring(0,maxCharsPerLine), xOffset,y);
y += fontHeight;
if (numPrintedLines==startingLineNumber+maxLinesPerPage) {
return Printable.PAGE_EXISTS;
}
}
curLineString = curLineString.substring(maxCharsPerLine, curLineString.length());
}
currentDocLineNumber += 1; // We have printed one more line from the document.
numPrintedLines++;
if (numPrintedLines>startingLineNumber) {
g.drawString(curLineString, xOffset,y);
y += fontHeight;
if (numPrintedLines==startingLineNumber+maxLinesPerPage) {
return Printable.PAGE_EXISTS;
}
}
}
// Now, the whole document has been "printed." Decide if this page had any text on it or not.
if (numPrintedLines > startingLineNumber) {
return Printable.PAGE_EXISTS;
}
return Printable.NO_SUCH_PAGE;
}
/**
* Prints a Document using a monospaced font, word wrapping on
* the characters ' ', '\t', '\n', ',', '.', and ';'. This method is
* expected to be called from Printable 'print(Graphics g)' functions.
*
* @param g The graphics context to write to.
* @param doc The javax.swing.text.Document to print.
* @param fontSize the point size to use for the monospaced font.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to expand tabs to.
*
* @see #printDocumentMonospaced
*/
public static int printDocumentMonospacedWordWrap(Graphics g, Document doc,
int fontSize, int pageIndex,
PageFormat pageFormat, int tabSize) {
g.setColor(Color.BLACK);
g.setFont(new Font("Monospaced", Font.PLAIN, fontSize));
// Initialize our static variables (these are used by our tab expander below).
tabSizeInSpaces = tabSize;
fm = g.getFontMetrics();
// Create our tab expander.
//RPrintTabExpander tabExpander = new RPrintTabExpander();
// Get width and height of characters in this monospaced font.
int fontWidth = fm.charWidth('w'); // Any character will do here, since font is monospaced.
int fontHeight = fm.getHeight();
int maxCharsPerLine = (int)pageFormat.getImageableWidth() / fontWidth;
int maxLinesPerPage = (int)pageFormat.getImageableHeight() / fontHeight;
final int startingLineNumber = maxLinesPerPage * pageIndex;
// The (x,y) coordinate to print at (in pixels, not characters).
// Since y is the baseline of where we'll start printing (not the top-left
// corner), we offset it by the font's ascent ( + 1 just for good measure).
xOffset = (int)pageFormat.getImageableX();
int y = (int)pageFormat.getImageableY() + fm.getAscent() + 1;
// A counter to keep track of the number of lines that WOULD HAVE been
// printed if we were printing all lines.
int numPrintedLines = 0;
// Keep going while there are more lines in the document.
currentDocLineNumber = 0; // The line number of the document we're currently on.
rootElement = doc.getDefaultRootElement(); // To shorten accesses in our loop.
numDocLines = rootElement.getElementCount(); // The number of lines in our document.
while (currentDocLineNumber -1) {
int spacesNeeded = tabSizeInSpaces - (tabIndex % tabSizeInSpaces);
StringBuilder stringBuilder = new StringBuilder();
for (int i=0; i maxCharsPerLine) {
int breakPoint = getLineBreakPoint(curLineString, maxCharsPerLine) + 1;
numPrintedLines++;
if (numPrintedLines > startingLineNumber) {
g.drawString(curLineString.substring(0,breakPoint), xOffset,y);
y += fontHeight;
if (numPrintedLines==startingLineNumber+maxLinesPerPage) {
return Printable.PAGE_EXISTS;
}
}
curLineString = curLineString.substring(breakPoint, curLineString.length());
}
currentDocLineNumber += 1; // We have printed one more line from the document.
numPrintedLines++;
if (numPrintedLines>startingLineNumber) {
g.drawString(curLineString, xOffset,y);
y += fontHeight;
if (numPrintedLines==startingLineNumber+maxLinesPerPage) {
return Printable.PAGE_EXISTS;
}
}
}
// Now, the whole document has been "printed." Decide if this page had any text on it or not.
if (numPrintedLines > startingLineNumber) {
return Printable.PAGE_EXISTS;
}
return Printable.NO_SUCH_PAGE;
}
/**
* Prints a Document using the specified font, word wrapping
* on the characters ' ', '\t', '\n', ',', '.', and ';'. This method is
* expected to be called from Printable 'print(Graphics g)' functions.
*
* @param g The graphics context to write to.
* @param textComponent The javax.swing.text.JTextComponent
* whose text you're printing.
* @param font The font to use for printing. If null, then
* textComponent's font is used.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to convert tabs to.
*
*/
public static int printDocumentWordWrap(Graphics g, JTextComponent textComponent,
Font font, int pageIndex,
PageFormat pageFormat,
int tabSize) {
// Initialize our graphics object.
g.setColor(Color.BLACK);
g.setFont(font!=null ? font : textComponent.getFont());
// Initialize our static variables (these are used by our tab expander below).
tabSizeInSpaces = tabSize;
fm = g.getFontMetrics();
int fontHeight = fm.getHeight();
final int lineLengthInPixels = (int)pageFormat.getImageableWidth();
final int maxLinesPerPage = (int)pageFormat.getImageableHeight() / fontHeight;
final int startingLineNumber = maxLinesPerPage * pageIndex;
// Create our tab expander.
RPrintTabExpander tabExpander = new RPrintTabExpander();
// The (x,y) coordinate to print at (in pixels, not characters).
// Since y is the baseline of where we'll start printing (not the top-left
// corner), we offset it by the font's ascent ( + 1 just for good measure).
xOffset = (int)pageFormat.getImageableX();
int y = (int)pageFormat.getImageableY() + fm.getAscent() + 1;
// A counter to keep track of the number of lines that WOULD HAVE been
// printed if we were printing all lines.
int numPrintedLines = 0;
// Keep going while there are more lines in the document.
Document doc = textComponent.getDocument();
rootElement = doc.getDefaultRootElement();
numDocLines = rootElement.getElementCount(); // The number of lines in our document.
currentDocLineNumber = 0; // The line number of the document we're currently on.
int startingOffset = 0; // Used when a line is so long it has to be wrapped.
while (currentDocLineNumber lineLengthInPixels) {
//System.err.println("'" + currentLineSeg + "' - " + currentLineLengthInPixels + "/" + LINE_LENGTH_IN_PIXELS);
// Remove any spaces and/or tabs from the end of the segment (would cause problems if you left 'em).
currentLineSeg = removeEndingWhitespace(currentLineSeg);
// currentPos will be the last position in the current text of a "line break character."
currentPos = -1;
String currentLineString = currentLineSeg.toString();
for (char breakChar : BREAK_CHARS) {
// "+1" below so we include the character on the line.
int pos = currentLineString.lastIndexOf(breakChar) + 1;
//if (pos>-1 && pos>currentPos)
// currentPos = pos;
if (pos > 0 && pos > currentPos && pos != currentLineString.length()) {
currentPos = pos;
}
}
// If we didn't find a line break character, we'll simply break the line at
// the last character that fits on a printed line.
// So here, we set currentPos to be the position of the last character that fits
// on the current printed line.
if (currentPos == -1) {
// Fix currentLineSeg so that it contains exactly enough text to fit in
// LINE_LENGTH_IN_PIXELS pixels...
currentPos = 0;
do {
currentPos++;
try {
doc.getText(currentLineStart+startingOffset, currentPos, currentLineSeg);
} catch (BadLocationException ble) {
System.err.println(ble);
return Printable.NO_SUCH_PAGE;
}
currentLineLengthInPixels = Utilities.
getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);
} while (currentLineLengthInPixels <= lineLengthInPixels);
currentPos--;
}
try {
doc.getText((currentLineStart+startingOffset), currentPos, currentLineSeg);
} catch (BadLocationException ble) {
System.err.println("BadLocationException in print (a):");
System.err.println("==> currentLineStart: " + currentLineStart +
"; startingOffset: " + startingOffset + "; currentPos: " + currentPos);
System.err.println("==> Range: " + (currentLineStart+startingOffset) + " - " +
(currentLineStart+startingOffset+currentPos));
ble.printStackTrace();
return Printable.NO_SUCH_PAGE;
}
currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);
} // End of while (currentLineLengthInPixels > LINE_LENGTH_IN_PIXELS).
startingOffset += currentPos; // Where to start (offset from line's start), since this line wraps.
} // End of else.
numPrintedLines++;
if (numPrintedLines>startingLineNumber) {
//g.drawString(currentLineSeg.toString(), xOffset,y);
Utilities.drawTabbedText(currentLineSeg, xOffset,y, g, tabExpander, 0);
y += fontHeight;
if (numPrintedLines==startingLineNumber+maxLinesPerPage) {
return Printable.PAGE_EXISTS;
}
}
}
// Now, the whole document has been "printed." Decide if this page had any text on it or not.
if (numPrintedLines > startingLineNumber) {
return Printable.PAGE_EXISTS;
}
return Printable.NO_SUCH_PAGE;
}
/**
* Removes any spaces or tabs from the end of the segment.
*
* @param segment The segment from which to remove tailing whitespace.
* @return segment with trailing whitespace removed.
*/
private static Segment removeEndingWhitespace(Segment segment) {
int toTrim = 0;
char currentChar = segment.setIndex(segment.getEndIndex()-1);
while ((currentChar==' ' || currentChar=='\t') && currentChar!=Segment.DONE) {
toTrim++;
currentChar = segment.previous();
}
String stringVal = segment.toString();
String newStringVal = stringVal.substring(0,stringVal.length()-toTrim);
return new Segment(newStringVal.toCharArray(), 0, newStringVal.length());
}
/**
* A tab expander for the document currently being printed with the
* font being used for the printing.
*/
private static class RPrintTabExpander implements TabExpander {
RPrintTabExpander() {
}
@Override
public float nextTabStop(float x, int tabOffset) {
if (tabSizeInSpaces == 0) {
return x;
}
int tabSizeInPixels = tabSizeInSpaces * fm.charWidth(' ');
int ntabs = (((int) x) - xOffset) / tabSizeInPixels;
return xOffset + ((ntabs + 1f) * tabSizeInPixels);
}
}
}