【问题标题】:java awt printable and printjava awt 可打印和打印
【发布时间】:2017-03-01 22:13:47
【问题描述】:

我想打印画布上的内容,结果发现了以下建议代码: //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();
    }

然后在canvas中绘制方法:

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

它打印了,但一些边距被剪掉了。我读到 awt.printable 启用了更好的边距控制,所以我将代码更改为:

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);
    }
}

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;
    }

}

这就解决了边距问题。问题是我不再在绘画事件中获得 PrintGraphics 的实例。它始终是一个 Graphics 对象,当从打印中调用绘制时,无法打印其他信息。我尝试将 Graphics 对象转换为 canvas.printAll 方法中的 PrintGraphics 对象,但无济于事。如何通过检查对象类型或通过其他方式重新获得区分所谓的绘制方法的能力?

【问题讨论】:

    标签: java canvas awt


    【解决方案1】:

    也许有点骇人听闻,但在下面的代码行中,带有额外参数的间接可能会暂时解决您的问题。

    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:除非您真的想要“复合打印”,否则最好让您 MyCanvas 实现 Printable 接口本身。
    这意味着:将 public int print(Graphics g, PageFormat pf, int pageIndex) 移动到 MyCanvas 内类本身 - 不会受到伤害,如果您想打印使用 MyCanvas 非公共成员计算的内容,它会有所帮助。

    【讨论】:

    • 目前,我调用方法canvas printAll,它继承自java.awt.component。反过来,它称为油漆。我认为不应该直接调用paint - 背景中正在发生某种事物的生命周期?上面的解决方案不是建议规避规则吗?让 canvas 实现 Printable 很有趣。我可以设置一个类变量打印标志,但是如何从画布中调用 printAll?
    • 我采纳了您的建议,让 MyCanvas 实现 Printable,设置一个类变量标志,然后在 paint 方法中测试该标志。我从 MyCanvas 中调用 printAll 方法。按预期工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多