简体   繁体   中英

java awt printable and print

I wanted to print what is on the canvas and came across this suggested code: //https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/awt/designspec/printing.html

PrintJob pjob = getToolkit().getPrintJob(new Frame(), "Print TimeGraph", null);
if(pjob !=null) {
    Graphics pg = pjob.getGraphics();
    if (pg != null) {
        canvas.printAll(pg);
        pg.dispose();   // flush page
    }
        pjob.end();
    }

Then in the canvas paint method:

@Override
public void paint(Graphics g) {
    if(g instanceof PrintGraphics){
       if(graphTitle != null){
          g.drawString ("Hello Printer",left+10,top+50);
        } 
    }
}

It printed but some of the margins were cut off. I read that awt.printable enabled better margin control so I changed the code to:

PrinterJob pj = PrinterJob.getPrinterJob();
PageFormat pf = pj.defaultPage();
Paper paper = new Paper();
double margin = 4.5; 
paper.setImageableArea(margin, margin, paper.getWidth() - margin * 2, paper.getHeight() - margin * 2);
pf.setPaper(paper);
pj.setPrintable(new MyPrintable(), pf);
if (pj.printDialog()) {
    try {
        pj.print();
    } catch (PrinterException pp) {
        System.out.println(pp);
    }
}

and

class MyPrintable implements Printable {
    public int print(Graphics g, PageFormat pf, int pageIndex) {
        if (pageIndex != 0)
          return NO_SUCH_PAGE;
    Graphics2D g2 = (Graphics2D) g;
    g2.translate(pf.getImageableX(), pf.getImageableY());
    canvas.printAll(g);
    return PAGE_EXISTS;
    }

}

And that solved the margin issue. The problem is that I no longer get an instanceof PrintGraphics in the paint event. Its always a Graphics object an there is no way to print additional information when paint is invoked from printing. I tried casting the Graphics object to a PrintGraphics object in the canvas.printAll method to no avail. How can I regain the ability to differentiate what called the paint method either by checking the object type or by some other means?

Perhaps hackish but an indirection with extra parameter, on the line of the code below, may solve your problem for the moment.

class MyCanvas {
  protected void doPaint(Graphics g, boolean forPrinter) {
    if(forPrinter){
       if(graphTitle != null){
          g.drawString ("Hello Printer",left+10,top+50);
        } 
    }
  }

  @Override
  public void paint(Graphics g) {
    this.doPaint(g, false);
  }
}

class MyPrintable implements Printable {
    public int print(Graphics g, PageFormat pf, int pageIndex) {
      if (pageIndex != 0)
          return NO_SUCH_PAGE;
      Graphics2D g2 = (Graphics2D) g;
      g2.translate(pf.getImageableX(), pf.getImageableY());

      // If on many pages, this will need to be handled better.
      // But as are ignoring the pageIndex, I assume 
      // you are on a single page and pleased to print everything on it
      canvas.doPaint(g, true);
      return PAGE_EXISTS;
    }
}

PS: unless you really want to have a "composite printable" it is much better to make you MyCanvas implement the Printable interface itself.
This implies: move the public int print(Graphics g, PageFormat pf, int pageIndex) inside the MyCanvas class itself - cannot hurt and it helps if you want to print something you compute using the MyCanvas non-public members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM