Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multi-page printing

Status
Not open for further replies.

VitriolUK

Programmer
Joined
Jul 26, 2004
Messages
2
Location
GB
I've been driving myself nuts with this one over the past week. I managed to handle printing a single page of text or images without too many problems, but multi-page printing is driving me nuts. The code I have at the moment is:

class PrintObject implements Printable
{
public String mText = "Error - No Text Found";
public boolean finish;

public int print (Graphics g, PageFormat format, int pageIndex)
{
boolean tempbo = finish;
finish = false;
AttributedString mStyledText = new AttributedString(
mText);

Graphics2D g2d = (Graphics2D) g;

g2d.translate(format.getImageableX(), format.getImageableY());

g2d.setPaint(Color.black);

Point2D.Float pen = new Point2D.Float();
AttributedCharacterIterator charIterator = mStyledText.getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(charIterator,
g2d.getFontRenderContext());
float wrappingWidth = (float) format.getImageableWidth();
int nextbreak = 0, where = 0;
boolean breaker, endbreak;

while ( (measurer.getPosition() < charIterator.getEndIndex()) && (!finish)) {

where = measurer.getPosition();
breaker = false;
endbreak = false;
nextbreak = 1;
while (!breaker) {
if (where + nextbreak >= charIterator.getEndIndex() - 1) {
breaker = true;
endbreak = true;
}
if (mText.charAt(where + nextbreak) == '\r') breaker = true;
else nextbreak++;
}

TextLayout layout;
if (endbreak) layout = measurer.nextLayout(wrappingWidth);
else layout = measurer.nextLayout(wrappingWidth, nextbreak + where, false);
pen.y += layout.getAscent();
float dx = layout.isLeftToRight() ? 0 :
(wrappingWidth - layout.getAdvance()); //cond ? true : false

layout.draw(g2d, pen.x + dx, pen.y);
pen.y += layout.getDescent() + layout.getLeading();
if ( (pen.y + layout.getAscent()+layout.getDescent()) >
(format.getImageableHeight() + format.getImageableY())) finish = true;
}

if (finish){
mText = mText.substring(where + nextbreak);
return PAGE_EXISTS;
}
else {
if (!tempbo) return NO_SUCH_PAGE;
else return PAGE_EXISTS;
}

}

}


Unfortunately, this seems to print only half of the pages. I've tried all sorts of stuff, including adding another class boolean to ensure each page is printed twice, but when I do that it won't stop printing (even though NO_SUCH_PAGE is being returned in the correct location).

Can anyone spot where I've gone wrong, or else point out a nice simple class or class library that'll handle printing a long string which takes up several pages of text. I've downloaded JFreeReport but it's much bulkier and has way more functionality than I need.

Oh, the class that calls that one is:


public class PrintWords{

private String mText = "Error - No Text Found";
private boolean finish;
private boolean second;

public PrintWords(String input) {
mText = input;
finish = true;
}

public void doprint(String input) {

PrinterJob job = PrinterJob.getPrinterJob();

PrintObject myPrinter = new PrintObject();
myPrinter.mText=mText;
myPrinter.finish=finish;

job.setPrintable(myPrinter);

if (job.printDialog())
{
try { job.print(); }
catch (PrinterException e) { System.out.println(e); }
}

}

}


Thanks all.
 
You have a bizarre little problem there. I tried your code out and determined that it always skipped the first and last pages. I tinkered with it for hours and was unable to change that behaviour even slightly.

I still plan to work on it, but in the meantime I've had some success with JPrint at


It's bulky too, but you can ignore most of the bulk if you want to.
 
Thanks for the link; I wouldn't worry too much about wasting time trying to figure it out; I'll try rewriting from scratch following a tutorial and see if it works better. In the mean time I wrote a class to print just one page, and then another which takes the string and splits it into chunks that'll fit on a page and then calls the print class multiple times. Which isn't ideal since you get the print dialog a bunch of times and each page goes to the print spool seperately, but will do for the moment.
 
One thing I found was that if you create a Pageable object that passes back the number of pages to print, the whole thing works a lot faster.

Since the Pageable also returns the Printable object used to render each page, you might consider incorporating this into your final solution.

Good luck!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top