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.
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.