何时是此代码中调用的可打印接口的打印方法和...?

时间:2011-07-06 07:05:35

标签: java printing

// Program to print simple text on a Printer

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.PrinterException;
import java.awt.print.*;

class Printer extends JPanel implements Printable  {

  JButton print;

  Printer() {
    buildGUI();
    hookUpEvents();
  }

  public void buildGUI() {
    JFrame fr = new JFrame("Program to Print on a Printer");
    JPanel p = new JPanel();
    print = new JButton("Print");
    setPreferredSize( new Dimension ( 200,200 ) );
    p.setBackground( Color.black );
    fr.add(p);
    p.add( print , BorderLayout.CENTER );
    fr.pack();
    fr.setVisible( true );
  }

  public void hookUpEvents() {
    print.addActionListener( new ActionListener() {
      public void actionPerformed( ActionEvent ae ) {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable( new Printer() );
        boolean doPrint = job.printDialog();
        if( doPrint ) {
          try {
            job.print();
          } catch( PrinterException exc) {
            System.out.println( exc );
          }
        } else {
          System.out.println("You cancelled the print");
        } 
      }
    });
  }

  public int print( Graphics g , PageFormat pf , int pageIndex) throws PrinterException{
    Graphics2D g2d = (Graphics2D)g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());
    g.drawString( "testing..." , 100 , 100 );
    return PAGE_EXISTS;
  }

  public static void main( String args[] ) {
    new Printer();
  }
}

在命令java Printer之后输出为:

enter image description here

但是当我点击打印时,以及以下窗口:

enter image description here

我再次得到了昔日的窗口。为什么会这样?

此计划何时调用print Printable interface方法?

当我设置= 200,200时,为什么我的窗口尺寸变小。

1 个答案:

答案 0 :(得分:2)

好的,所以你有三个问题:

首先:你的窗口很小的原因是因为你正在使用jf.pack()以及边框布局,这使你的JFrame显示它所包含的所有组件所需的大小没有额外的空间。您可以将布局设置为null并丢失jf.pack()部分,但这通常不是推荐的做法。

第二个:该窗口第二次弹出,因为你在那里的监听器中创建了同一个对象的第二个实例:

job.setPrintable( new Printer() );

“new Printer()”部分创建另一个Printer对象,再次调用UI创建等。

您可以创建内部类而不是匿名类,以便能够使用“this”来引用当前的Printer对象。

你的hookUpEvents()方法是这样的:

public void hookUpEvents() {
  MyActionListener mal = new MyActionListener();
  print.addActionListener(mal); {
}

然后,在同一个类的其他地方创建这样的内部类:

private class MyActionListener implements ActionListener{
  public void actionPerformed(ActionEvent ae) {
    PrinterJob job = PrinterJob.getPrinterJob();
    job.setPrintable(Printer.this);
    boolean doPrint = job.printDialog();
     if( doPrint ) {
       try {
        job.print();
       }  
       catch( PrinterException exc) {
           System.out.println( exc );
       }
     }  
     else {
        System.out.println("You cancelled the print"); 
      } 
    }
}

第三:当您键入:“job.print()”时会调用print()方法,因为您正在从界面覆盖该方法。接口中的那个实际上从未被调用,因为你的调用是相反的,这是你想要的,因为你定义了它必须做的事情。

我希望现在能回答你的问题。

编辑:我刚刚测试了类似的东西,我想你可以在匿名类中输入Printer.this来使它工作而不是创建一个内部类,这会让你改变方式更少的代码