私は大きなプログラムで作業してきましたが、その機能の1つは、メインウィンドウのコンテンツを印刷することです。 APIを確認したところ、次の例が見つかりました。
http://docs.Oracle.com/javase/tutorial/2d/printing/gui.html
それは非常に役に立ちました、私はこれを私の印刷ボタンのactionperformedメソッド内に配置することによって私のプログラムでそのコードを使用しようとしました:
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
印刷ボタンをクリックすると、プリンタダイアログが表示され、印刷するように指示すると、空白のドキュメントが印刷されます。 APIの例で見てきたように、上記のコードだけが必要なわけではないことはわかっていますが、print()メソッドがあるようですが、明らかに呼び出されないため、かなり混乱します。何度も電話して使ってみましたが、うまくいきませんでした。
また、最終的に印刷するときは、ウィンドウを横向きで印刷する必要があり、スケーリングが必要になる場合もあると思います。それを行う方法についてのアイデアはありますか?
このコードを正常に実装するのに役立つヘルプがあればいいのですが。ドキュメントを確認するだけで自分でできるはずですが(2日近く試しました)、うまくいきません。私はインターネットを通して私が知っているすべてのプログラミングを学びました。どんな助けでも大歓迎です。
これが簡単な解決策です。 printableを実装するPrinterクラスがあり、印刷ジョブを処理します。
public static class Printer implements Printable {
final Component comp;
public Printer(Component comp){
this.comp = comp;
}
@Override
public int print(Graphics g, PageFormat format, int page_index)
throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
// get the bounds of the component
Dimension dim = comp.getSize();
double cHeight = dim.getHeight();
double cWidth = dim.getWidth();
// get the bounds of the printable area
double pHeight = format.getImageableHeight();
double pWidth = format.getImageableWidth();
double pXStart = format.getImageableX();
double pYStart = format.getImageableY();
double xRatio = pWidth / cWidth;
double yRatio = pHeight / cHeight;
Graphics2D g2 = (Graphics2D) g;
g2.translate(pXStart, pYStart);
g2.scale(xRatio, yRatio);
comp.Paint(g2);
return Printable.PAGE_EXISTS;
}
}
次に、それを印刷するには:
JFrame yourComponent = new JFrame();
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat preformat = pjob.defaultPage();
preformat.setOrientation(PageFormat.LANDSCAPE);
PageFormat postformat = pjob.pageDialog(preformat);
//If user does not hit cancel then print.
if (preformat != postformat) {
//Set print component
pjob.setPrintable(new Printer(yourComponent), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
これが私のアイデアのひねりです...
フィットするように印刷...
塗りつぶすために印刷...
public class TestPrinting {
public static void main(String[] args) {
try {
printComponentToFile(new PrintForm(), true);
printComponentToFile(new PrintForm(), false);
} catch (PrinterException exp) {
exp.printStackTrace();
}
}
public static void printComponent(JComponent comp, boolean fill) throws PrinterException {
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = pjob.defaultPage();
pf.setOrientation(PageFormat.LANDSCAPE);
PageFormat postformat = pjob.pageDialog(pf);
if (pf != postformat) {
//Set print component
pjob.setPrintable(new ComponentPrinter(comp, fill), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
}
public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()),
(int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrinter cp = new ComponentPrinter(comp, fill);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrinter implements Printable {
private Component comp;
private boolean fill;
public ComponentPrinter(Component comp, boolean fill) {
this.comp = comp;
this.fill = fill;
}
@Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
g2.translate(format.getImageableX(), format.getImageableY());
double width = (int) Math.floor(format.getImageableWidth());
double height = (int) Math.floor(format.getImageableHeight());
if (!fill) {
width = Math.min(width, comp.getPreferredSize().width);
height = Math.min(height, comp.getPreferredSize().height);
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
if (comp.getParent() == null) {
comp.addNotify();
}
comp.validate();
comp.doLayout();
comp.printAll(g2);
if (comp.getParent() != null) {
comp.removeNotify();
}
return Printable.PAGE_EXISTS;
}
}
}
幅広い問題のいくつか...
addNotify
/validate
/doLayout
。画面に表示されている場合でも、境界を変更すると、これらのメソッドを呼び出す必要がある場合があります。