HardcopyWriterpublic class HardcopyWriter extends Writer A character output stream that sends output to a printer. |
Fields Summary |
---|
protected PrintJob | job | protected Graphics | page | protected String | jobname | protected int | fontsize | protected String | time | protected Dimension | pagesize | protected int | pagedpi | protected Font | font | protected Font | headerfont | protected FontMetrics | metrics | protected FontMetrics | headermetrics | protected int | x0 | protected int | y0 | protected int | width | protected int | height | protected int | headery | protected int | charwidth | protected int | lineheight | protected int | lineascent | protected int | chars_per_line | protected int | lines_per_page | protected int | charnum | protected int | linenum | protected int | pagenum | private boolean | last_char_was_return | protected static Properties | printprops |
Constructors Summary |
---|
public HardcopyWriter(Frame frame, String jobname, int fontsize, double leftmargin, double rightmargin, double topmargin, double bottommargin)The constructor for this class has a bunch of arguments:
The frame argument is required for all printing in Java.
The jobname appears left justified at the top of each printed page.
The font size is specified in points, as on-screen font sizes are.
The margins are specified in inches (or fractions of inches).
// Get the PrintJob object with which we'll do all the printing.
// The call is synchronized on the static printprops object, which
// means that only one print dialog can be popped up at a time.
// If the user clicks Cancel in the print dialog, throw an exception.
Toolkit toolkit = frame.getToolkit(); // get Toolkit from Frame
synchronized(printprops) {
job = toolkit.getPrintJob(frame, jobname, printprops);
}
if (job == null)
throw new PrintCanceledException("User cancelled print request");
pagesize = job.getPageDimension(); // query the page size
pagedpi = job.getPageResolution(); // query the page resolution
// Bug Workaround:
// On windows, getPageDimension() and getPageResolution don't work, so
// we've got to fake them.
if (System.getProperty("os.name").regionMatches(true,0,"windows",0,7)){
// Use screen dpi, which is what the PrintJob tries to emulate
pagedpi = toolkit.getScreenResolution();
// Assume a 8.5" x 11" page size. A4 paper users must change this.
pagesize = new Dimension((int)(8.5 * pagedpi), 11*pagedpi);
// We also have to adjust the fontsize. It is specified in points,
// (1 point = 1/72 of an inch) but Windows measures it in pixels.
fontsize = fontsize * pagedpi / 72;
}
// Compute coordinates of the upper-left corner of the page.
// I.e. the coordinates of (leftmargin, topmargin). Also compute
// the width and height inside of the margins.
x0 = (int)(leftmargin * pagedpi);
y0 = (int)(topmargin * pagedpi);
width = pagesize.width - (int)((leftmargin + rightmargin) * pagedpi);
height = pagesize.height - (int)((topmargin + bottommargin) * pagedpi);
// Get body font and font size
font = new Font("Monospaced", Font.PLAIN, fontsize);
metrics = frame.getFontMetrics(font);
lineheight = metrics.getHeight();
lineascent = metrics.getAscent();
charwidth = metrics.charWidth('0"); // Assumes a monospaced font!
// Now compute columns and lines will fit inside the margins
chars_per_line = width / charwidth;
lines_per_page = height / lineheight;
// Get header font information
// And compute baseline of page header: 1/8" above the top margin
headerfont = new Font("SansSerif", Font.ITALIC, fontsize);
headermetrics = frame.getFontMetrics(headerfont);
headery = y0 - (int)(0.125 * pagedpi) -
headermetrics.getHeight() + headermetrics.getAscent();
// Compute the date/time string to display in the page header
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.SHORT);
df.setTimeZone(TimeZone.getDefault());
time = df.format(new Date());
this.jobname = jobname; // save name
this.fontsize = fontsize; // save font size
|
Methods Summary |
---|
public void | close()This is the close() method that all Writer subclasses must implement.
Print the pending page (if any) and terminate the PrintJob.
synchronized(this.lock) {
if (page != null) page.dispose(); // Send page to the printer
job.end(); // Terminate the job
}
| public void | flush()This is the flush() method that all Writer subclasses must implement.
There is no way to flush a PrintJob without prematurely printing the
page, so we don't do anything. /* do nothing */
| public int | getCharactersPerLine()Return the number of columns of characters that fit on the page return this.chars_per_line;
| public int | getLinesPerPage()Return the number of lines that fit on a page return this.lines_per_page;
| protected void | newline()This internal method begins a new line
charnum = 0; // Reset character number to 0
linenum++; // Increment line number
if (linenum >= lines_per_page) { // If we've reached the end of page
page.dispose(); // send page to printer
page = null; // but don't start a new page yet.
}
| protected void | newpage()This internal method begins a new page and prints the header.
page = job.getGraphics(); // Begin the new page
linenum = 0; charnum = 0; // Reset line and char number
pagenum++; // Increment page number
page.setFont(headerfont); // Set the header font.
page.drawString(jobname, x0, headery); // Print job name left justified
String s = "- " + pagenum + " -"; // Print the page # centered.
int w = headermetrics.stringWidth(s);
page.drawString(s, x0 + (this.width - w)/2, headery);
w = headermetrics.stringWidth(time); // Print date right justified
page.drawString(time, x0 + width - w, headery);
// Draw a line beneath the header
int y = headery + headermetrics.getDescent() + 1;
page.drawLine(x0, y, x0+width, y);
// Set the basic monospaced font for the rest of the page.
page.setFont(font);
| public void | pageBreak()End the current page. Subsequent output will be on a new page. synchronized(this.lock) { newpage(); }
| public void | setFontStyle(int style)Set the font style. The argument should be one of the font style
constants defined by the java.awt.Font class. All subsequent output
will be in that style. This method relies on all styles of the
Monospaced font having the same metrics.
synchronized (this.lock) {
// Try to set a new font, but restore current one if it fails
Font current = font;
try { font = new Font("Monospaced", style, fontsize); }
catch (Exception e) { font = current; }
// If a page is pending, set the new font. Otherwise newpage() will
if (page != null) page.setFont(font);
}
| public void | write(char[] buffer, int index, int len)This is the write() method of the stream. All Writer subclasses
implement this. All other versions of write() are variants of this one
synchronized(this.lock) { // For thread safety
// Loop through all the characters passed to us
for(int i = index; i < index + len; i++) {
// If we haven't begun a page (or a new page), do that now.
if (page == null) newpage();
// If the character is a line terminator, then begin new line,
// unless it is a \n immediately after a \r.
if (buffer[i] == '\n") {
if (!last_char_was_return) newline();
continue;
}
if (buffer[i] == '\r") {
newline();
last_char_was_return = true;
continue;
}
else last_char_was_return = false;
// If it some other non-printing character, ignore it.
if (Character.isWhitespace(buffer[i]) &&
!Character.isSpaceChar(buffer[i]) && (buffer[i] != '\t"))
continue;
// If no more characters will fit on the line, start new line.
if (charnum >= chars_per_line) {
newline();
// Also start a new page, if necessary
if (page == null) newpage();
}
// Now print the character:
// If it is a space, skip one space, without output.
// If it is a tab, skip the necessary number of spaces.
// Otherwise, print the character.
// It is inefficient to draw only one character at a time, but
// because our FontMetrics don't match up exactly to what the
// printer uses we need to position each character individually
if (Character.isSpaceChar(buffer[i])) charnum++;
else if (buffer[i] == '\t") charnum += 8 - (charnum % 8);
else {
page.drawChars(buffer, i, 1,
x0 + charnum * charwidth,
y0 + (linenum*lineheight) + lineascent);
charnum++;
}
}
}
|
|