Welcome to My World (www.dgmayor.com)

소프트웨어/자바 GUI & C# 등...

50. 단일 패널 인쇄 자바

dgmayor 2022. 5. 13. 15:01
728x90

1. PrintJob pb = p1.getToolkit().getPrintJob(jf, "프린트 테스트", null);

if(pb != null) {
Graphics pg = pb.getGraphics();
if(pg != null) {
pb.print(pg);
pg.dispose();
pb.end();
}
}
}

2. package Test;

import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.JFrame;

public class Print_Test implements Printable {

@Override
public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {

if (pi > 0) { return NO_SUCH_PAGE; }

g.fillRect(5, 5, 210, 140);

return PAGE_EXISTS;
}

public static void main(String args[]) {

JFrame f = new JFrame("Hello World Printer");

f.pack();
f.setVisible(true);

PrinterJob job = PrinterJob.getPrinterJob();

PageFormat pf = new PageFormat();
Paper p = new Paper();

p.setSize(280, 160);
p.setImageableArea(0, 0, 280, 160);

pf.setOrientation(PageFormat.PORTRAIT);
pf.setPaper(p);
job.setPrintable(new Print_Test(), pf);

boolean ok = job.printDialog();
if (ok) {

try {
job.print();
System.out.println(p.getWidth() + "너비" + "  " + p.getHeight() + " 높이");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

}

 

크기 조절 노가다로 겨우 해결;;

 

3.

package com.test.convert; 

import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 

import javax.imageio.ImageIO; 

public class ConvertImageWithDimensionsAndPrint { 
    private static final int IMAGE_WIDTH = 800; 
    private static final int IMAGE_HEIGHT = 1000; 

public static void main(String[] args) { 
    try { 
     String sourceDir = "C:/Images/04-Request-Headers_1.png"; 
     File sourceFile = new File(sourceDir); 
     String destinationDir = "C:/Images/ConvertedImages/";//Converted images save here 
     File destinationFile = new File(destinationDir); 
     if (!destinationFile.exists()) { 
      destinationFile.mkdir(); 
     } 
     if (sourceFile.exists()) { 
      String fileName = sourceFile.getName().replace(".png", ""); 
      BufferedImage bufferedImage = ImageIO.read(sourceFile); 
      int type = bufferedImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : bufferedImage.getType(); 

      BufferedImage resizedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, type); 
      Graphics2D graphics2d = resizedImage.createGraphics(); 
      graphics2d.drawImage(bufferedImage, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);//resize goes here 
      graphics2d.dispose(); 

      ImageIO.write(resizedImage, "png", new File(destinationDir + fileName +".png")); 

      int oldImageWidth = bufferedImage.getWidth(); 
      int oldImageHeight = bufferedImage.getHeight(); 
      System.out.println(sourceFile.getName() +" OldFile with Dimensions: "+ oldImageWidth +"x"+ oldImageHeight); 
      System.out.println(sourceFile.getName() +" ConvertedFile converted with Dimensions: "+ IMAGE_WIDTH +"x"+ IMAGE_HEIGHT); 

      //Print the image file 
      PrintActionListener printActionListener = new PrintActionListener(resizedImage); 
      printActionListener.run(); 
     } else { 
      System.err.println(destinationFile.getName() +" File not exists"); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
} 

Reference

package com.test.convert; 

import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.awt.print.PageFormat; 
import java.awt.print.Printable; 
import java.awt.print.PrinterException; 
import java.awt.print.PrinterJob; 

public class PrintActionListener implements Runnable { 

private BufferedImage image; 

public PrintActionListener(BufferedImage image) { 
    this.image = image; 
} 

@Override 
public void run() { 
    PrinterJob printJob = PrinterJob.getPrinterJob(); 
    printJob.setPrintable(new ImagePrintable(printJob, image)); 

    if (printJob.printDialog()) { 
     try { 
      printJob.print(); 
     } catch (PrinterException prt) { 
      prt.printStackTrace(); 
     } 
    } 
} 

public class ImagePrintable implements Printable { 

    private double x, y, width; 

    private int orientation; 

    private BufferedImage image; 

    public ImagePrintable(PrinterJob printJob, BufferedImage image) { 
     PageFormat pageFormat = printJob.defaultPage(); 
     this.x = pageFormat.getImageableX(); 
     this.y = pageFormat.getImageableY(); 
     this.width = pageFormat.getImageableWidth(); 
     this.orientation = pageFormat.getOrientation(); 
     this.image = image; 
    } 

    @Override 
    public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException { 
     if (pageIndex == 0) { 
      int pWidth = 0; 
      int pHeight = 0; 
      if (orientation == PageFormat.PORTRAIT) { 
       pWidth = (int) Math.min(width, (double) image.getWidth()); 
       pHeight = pWidth * image.getHeight()/image.getWidth(); 
      } else { 
       pHeight = (int) Math.min(width, (double) image.getHeight()); 
       pWidth = pHeight * image.getWidth()/image.getHeight(); 
      } 
      g.drawImage(image, (int) x, (int) y, pWidth, pHeight, null); 
      return PAGE_EXISTS; 
     } else { 
      return NO_SUCH_PAGE; 
     } 
    } 

} 


}자바로 프린팅 하기

Java2(Java 1.2) 에서 드디어 쓸만한 Print API가 등장했네요.


1. 우선 알아야 할것들.

우선 프린팅을 할려면 뭐가 필요할까요? 프린팅에 관한 클래스가 필요합니다.
자바는 멀티 플랫폼을 지원함으로 특정 플랫폼에만 해당 하는 클래스는 만들수가
없죠. 따라서 우린 직접 프린팅 클래스를 인스턴스화 하는것이 아니라 프린팅
클래스의 Static Method를 통하여 인스턴스를 얻습니다.

프린팅 클래스 : java.awt.print.PrinterJob

PrinterJob myPrnJob = PrinterJob.getPrinterJob();

프린팅은 시스템이 하는것이지만 그 내용은 당연히 우리가 제공해야 하는것이겠죠.
자 시스템에게 우리가 프린터 할 내용을 제공해야 합니다. 어떤 방법이 좋을까요?
객체지향언어인 만큼 우리 내용을 클래스로 제공하는것도 괜찮은 방법 같아 보입
니다. 자바는 이럴 경우 인터페이스를 사용하죠? 종전에도 그랬듯이 말입니다.

2. 프린팅 인터페이스

프린팅 인터페이스 : java.awt.print.Printable

자 이름이 그럴싸 하죠? 내용을 프린팅하기 원하는 클래스는 위의 인터페이스를
구현해주어야 하는거죠.

인터페이스이니 안에는 abstract Method가 있겠네요. 한번 볼까요.

public interface Printable {
int PAGE_EXISTS = 0;
int NO_SUCH_PAGE = 1;

int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException;
}

간단한 인터페이스입니다. 두개의 Variable 과 하나의 메써드가 있네요.
우리가 구현해야할 하나의 메써드를 살펴보죠.

int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException;

자 3개의 인수를 받고 PrinterException 예외를 던지는군요.

Graphics graphics : 그래픽 디바이스 핸들이 넘어 오는군요. 사실상 여기에
프린터 디바이스 핸들이 넘어 오는것이죠. 여기다 내용을 그리면 실제로 프
린팅이 되는것이죠.

자 두번째는

PageFormat pageFormat : 자 클래스 이름을 보니 프린팅될 포맷이 넘어오는군요.
종이의 크기라든지, 실제 프린팅 될수 있는 공간등이 넘어 옵니다. 자세한
내용은 차차 하기로 하죠.

마지막으로는

int pageIndex : 이것은 실제 시스템이 지금 몇페이지를 찍을 테니 그에 대한
정보를 다오. 하는 식으로 넘어 오는것입니다.
내가 프린팅 할 정보 이상의 페이지를 요구할때는 그런 페이지가 없다구 리턴
해주면 됩니다. 만일 있다면 graphics 인스턴스에다 렌더링 한후에 페이지가
존재한다고 리턴해주는거죠. 살짝 예를 들어보면

if (pageIndex >= 1) return Printable.NO_SUCH_PAGE;
graphics.drawString(10,10,"Hello");
return Printable.PAGE_EXISTS;

가 되겠죠.

자 처음에도 얘기 했듯이 프린팅은 우리가 하는게 아닙니다. 시스템이 해주는거죠.
따라서 우린 저함수를 구현할 뿐이지 실제로 부르는건 시스템이 알아서 할겁니다.
자 위의 예제를 복습할만한 간단한(?) 예제를 구현해 보았습니다.

RGB 값을 나타내는 삼각형을 프린터 하는것인데요.. 뭐 그 코드는 중요한게 아니구
우리에게 중요한건 Printable 인터페이스를 어떻게 구현했나 하는것이죠.


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

public class PrintExample {

public static RGBTriangle panel;
public static JButton printButton;

public PrintExample() {
panel = new RGBTriangle();

printButton = new JButton(" 프린트 ");

printButton.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
PrinterJob prnJob = PrinterJob.getPrinterJob();
prnJob.setPrintable(panel);
if (! prnJob.printDialog())
return;
try {
prnJob.print();
} catch (PrinterException pe) {
System.out.println("프린터 에러 " + pe.getMessage() );
}
}
} );
}

public static void main(String [] args) {
new PrintExample();
JFrame frame = new JFrame ("프린터 예제");

frame.addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

frame.getContentPane().add(panel,BorderLayout.CENTER);
frame.getContentPane().add(printButton, BorderLayout.SOUTH);

frame.setSize(300,300);
frame.setVisible(true);
}
}

class RGBTriangle extends JPanel implements Printable {

private int color = 256;

private int width ;
private int height ;

private Polygon poly;
private Point R,G,B;
private Point current;

int r,g,b;

public RGBTriangle() {
width = color;
height = (int) Math.round ( Math.sqrt( width * width - (width/2) * (width/2) ) );
R = new Point (0,0);
G = new Point(width,0);
B = new Point(width/2,height);
current = new Point();

poly = new Polygon();
poly.addPoint(R.x,R.y);
poly.addPoint(G.x,G.y);
poly.addPoint(B.x,B.y);
}

public int print(Graphics pg, PageFormat pageFormat , int pageIndex)
throws PrinterException {
if (pageIndex >= 1)
return NO_SUCH_PAGE;
pg.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());

paint(pg);
return PAGE_EXISTS;
}

public void paint(Graphics gra) {
for (int i=0;i<256;i++) {
for (int j=0;j<256;j++) {
if (contains(i,j) ){
current.setLocation(i,j);
r = length ( R , current );
g = length ( G , current );
b = length ( B , current );
gra.setColor(new Color(certify(r),certify(g),certify(b)));

// 한 픽셀에 점을 그린다.
// 한 픽셀에 점을 그리는 함수를 몰라서
// 아래 함수를 사용했음.
gra.drawLine(i-1,j-1,i,j);
}
}
}
}

public int certify(int r) {
if (r >=256)
return 255;
else if (r < 0 )
return 0;
else
return r;
}

public boolean contains (int x,int y) {
return poly.contains( x, y );
}

/* 두점 사이의 길이를 반환한다 */
public int length (Point p1,Point p2) {
return (int ) Math.round ( Math.sqrt ( (p1.x - p2.x )* (p1.x - p2.x)
+ (p1.y - p2.y)*(p1.y - p2.y) ) );
}
}

위의 코드를 컴파일하고 실행 시켜보세요.

ps. 자바의 프린팅 모델은 "콜백 프린팅 모델" 이라고 불립니다. 적은 메모리
와 적은 하드 공간으로도 프린팅 가능할수 있도록 실제로 프린터가 렌더링
할때 우리 함수를 호출합니다. 바꿔 말해서.. 굉장히 느립니다. 위의 코드는
프린팅 작업을 따로 쓰레드로 빼지 않았습니다. 따라서 프린팅 작업이 끝날때
까지 우리 프로그램은 아무것도 할수가 없죠.

ps2. 자 위에코드로 수행 시키다 보면 프린팅할 페이지가 1~9999 로 나타나는
걸 알 수 있는데, 위의 코드로는 고칠 수가 없습니다. 실제로 프린팅 시스템
은 프린팅을 하기전까지 우리 내용에 대한 정보를 가질수가 없기 때문입니다.

ps3. 위의 코드는 JDK 1.2.1로 컴파일하고 실행시킨 것입니다. 그 이하 버전에
서는 동작하지 않을수도 있습니다. 실제로 JDK 내에서 프린팅은 아직 버그가
많습니다.

더 많은 예제는 하단

 

ToolkitDelegate.getPrintJob(...)

public PrintJob getPrintJob(Frame frame, String jobtitle,
              JobAttributes jobAttributes, PageAttributes pageAttributes) {
 return getUnderlyingToolkit().getPrintJob(frame, jobtitle, jobAttributes,
                      pageAttributes);
}
  •  

ToolkitDelegate.getPrintJob(...)

public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) {
 return getUnderlyingToolkit().getPrintJob(frame, jobtitle, props);
}
  •  

How can I print a single JPanel's contents?

 private void PritnActionPerformed(java.awt.event.ActionEvent evt) {
  // TODO add your handling code here:
  Toolkit tkp = jPanel1.getToolkit();
  PrintJob pjp = tkp.getPrintJob(this, null, null);
  Graphics g = pjp.getGraphics();
  jPanel1.print(g);
  g.dispose();
  pjp.end();
}
  •  

Editor.print()

void print () {
  PrintJob pjob = Toolkit.getDefaultToolkit().getPrintJob(this, "Cool Stuff", p);
  if (pjob != null) {
    Graphics pg = pjob.getGraphics( );
    if (pg != null) {
      String s = ta.getText();
      printString(pjob, pg, s);
      pg.dispose( );    
    }
    pjob.end( );
  }
}
  •  

DebugOutput.print(...)

public static void print(final String title, final String text) {
  final Frame parent = new Frame();
  final PrintJob job = Toolkit.getDefaultToolkit().getPrintJob(parent, "Print " + title, new Properties());
  if (job != null) {
    final Graphics graphic = job.getGraphics();
    // Dimension pageSize = job.getPageDimension();
    if (graphic != null) {
      graphic.translate(10, 10);
      final int x = 50;
      int y = 50;
      graphic.setFont(TITLE_FONT);
      final int height = graphic.getFontMetrics().getAscent();
      final int width = graphic.getFontMetrics().stringWidth(title);
      graphic.drawRect(x - 10, y - 10 - height, width + 20, height + 20);
      graphic.drawString(title, x, y);
      y += graphic.getFontMetrics().getHeight();
      y += 20;
      graphic.setFont(TEXT_FONT);
      final StringTokenizer tk = new StringTokenizer(text, "\n\r");
      while (tk.hasMoreTokens()) {
        final String line = tk.nextToken();
        graphic.drawString(line, x, y);
        y += graphic.getFontMetrics().getHeight();
      }
      graphic.dispose();
    }
    job.end();
  }
  parent.dispose();
}
  •  

Editor.print()

void print () {
  PrintJob pjob = Toolkit.getDefaultToolkit().getPrintJob(this, "Cool Stuff", p);
  if (pjob != null) {
    Graphics pg = pjob.getGraphics( );
    if (pg != null) {
      String s = ta.getText();
      printString(pjob, pg, s);
      pg.dispose( );    
    }
    pjob.end( );
  }
}
  •  

PrintDemo1.actionPerformed(...)

  /** Action handler does the work of the printing test. */
  public void actionPerformed(ActionEvent evt) {
    Graphics pg = null;    // refers to current page
    System.out.println("Doing print");
    pjob = getToolkit().getPrintJob(this,
      "Printing Test", (Properties)null);
    if (pjob == null)          // User cancelled??
      return;
    Dimension pDim = pjob.getPageDimension();
    int pRes = pjob.getPageResolution();
    System.out.println("Page size " + pDim + "; Res " + pRes);
    // Print up to NPAGES
    for (int pgNum=0; pgNum<nPages; pgNum++) {
      System.out.println("Starting page # " + pgNum);
      pg = pjob.getGraphics();
      if (pg == null) 	// ??
        return;
      // setColor needed on Solaris (a bug!?)
      pg.setColor(Color.black);
      pg.setFont(new Font("Helvetica", Font.PLAIN, 48));
      pg.drawString("Hello World", 200, 200);
      pg.drawString("Page " + pgNum, 300, 300);
      System.out.println("Disposing of page " + pgNum);
      pg.dispose(); // flush page
      System.out.println("Disposed of page " + pgNum);
    }
    pjob.end();    // total end of print job.
    pjob = null;    // avoid redundant calls to pjob.end()
  }
}
  •  

PrintDemo0.print(...)

pjob = getToolkit().getPrintJob(this,
  "Printing Test", (Properties)null);
if (pjob == null)          // User cancelled??
  •  

PrintFile.print(...)

  /** Print a file by File */
  public void print(Reader ifile) {
    BufferedReader is = new BufferedReader(ifile);
    Graphics g = null;    // refers to current page
    System.out.println("Doing print");
    pjob = getToolkit().getPrintJob(this,
      "Printing Test", (Properties)null);
    if (pjob == null)          // User cancelled??
      return;
    Dimension pDim = pjob.getPageDimension();
    int pRes = pjob.getPageResolution();
    System.out.println("Page size " + pDim + "; Res " + pRes);
    g = pjob.getGraphics();
    g.setColor(Color.black);
    g.setFont(new Font("SansSerif", Font.PLAIN, 12));
    int y = 100;
    String line;
    try {
      while ((line = is.readLine()) != null) {
        g.drawString(line, 10, y+=18);
      }
    } catch (IOException e) {
      System.err.println(e);
    }
    // g.drawString("Page " + pgNum, 300, 300);
    g.dispose(); // flush page
    pjob.end();    // total end of print job.
    pjob = null;    // avoid redundant calls to pjob.end()
  }
}
  •  

PrintFile.print(...)

  /** Print a file by File 
   * @throws IOException */
  public void print(Reader ifile) throws IOException {
    BufferedReader is = new BufferedReader(ifile);
    System.out.println("Doing print");
    pjob = getToolkit().getPrintJob(this,
      "Printing Test", (Properties)null);
    if (pjob == null)          // User cancelled??
      return;
    Dimension pDim = pjob.getPageDimension();
    int pRes = pjob.getPageResolution();
    System.out.println("Page size " + pDim + "; Res " + pRes);
    Graphics g = pjob.getGraphics();
    if (g == null) {
      System.err.println("Err, Graphics object from PrintJob is null!");
      return;
    }
    g.setColor(Color.black);
    g.setFont(new Font("SansSerif", Font.PLAIN, 12));
    int y = 100;
    String line;
    while ((line = is.readLine()) != null) {
      g.drawString(line, 10, y+=18);
    }
    // g.drawString("Page " + pgNum, 300, 300);
    g.dispose(); // flush page
    pjob.end();    // total end of print job.
    pjob = null;    // avoid redundant calls to pjob.end()
  }
}
  •  

PrintOption.execute(...)

public void execute(final Workspace workspace, final View view, final Location at) {
  Frame frame = new Frame();
  PrintJob job = Toolkit.getDefaultToolkit().getPrintJob(frame, "Print object", null);
  if (job != null) {
    Graphics pg = job.getGraphics();
    Dimension pageSize = job.getPageDimension();
    if (pg != null) {
      pg.translate(LEFT, HEIGHT);
      pg.drawRect(0, 0, pageSize.width - LEFT - 1, pageSize.height - HEIGHT - 1);
      view.print(new PrintCanvas(pg, view));
      pg.dispose();
    }
    job.end();
  }
  frame.dispose();
}
  •  

PrintOption.execute(...)

@Override
public void execute(final Workspace workspace, final View view, final Location at) {
  final Frame frame = new Frame();
  final PrintJob job = Toolkit.getDefaultToolkit().getPrintJob(frame, "Print object", null);
  if (job != null) {
    final Graphics pg = job.getGraphics();
    final Dimension pageSize = job.getPageDimension();
    if (pg != null) {
      pg.translate(LEFT, HEIGHT);
      pg.drawRect(0, 0, pageSize.width - LEFT - 1, pageSize.height - HEIGHT - 1);
      view.print(new PrintCanvas(pg, view));
      pg.dispose();
    }
    job.end();
  }
  frame.dispose();
}
  •  

BuPrinter.print(...)

pp.put("awt.print.paperSize","a4");
PrintJob pjob=_parent.getToolkit().getPrintJob(_parent,_name,pp);
if(pjob!=null)
  •  

PrintFileAction.printQuartz(...)

pageAttr.setMedia(PageAttributes.MediaType.A4);
pageAttr.setPrinterResolution((int) resolution);
final PrintJob pj = frame.getToolkit().getPrintJob(
    frame,
    "Job Title",
728x90