Imprimindo Components com java.awt.print

3 respostas
J

Oi pessoal,

Eu estive apanhando um bocado para conseguir imprimir JTables aqui em casa. Teoricamente, isto deveria ser uma tarefa fácil, visto que a classe possui um método print() desde a versão 1.5. Entretanto, aqui em casa a impressora ou não imprimia nada, ou não imprimia o conteúdo das células da JTable. Depois de pesquisar um bocado vi que o XP pode ter problemas com o javax.swing. Eu não lembro mais o link, mas é um bug relatado inclusive no site da Microsoft.

Resumindo, eu na verdade não tenho dúvidas, apenas criei o tópico para enviar um código que acabei de fazer e testar para imprimir Components apenas usando java.awt.print. Se mais alguém tiver outros códigos mais simples, ou quiser me ajudar a descobrir por que o javax.swing não funciona direito aqui eu agradeço.

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

public class Imprimir implements Printable {
	private PageFormat pFormat;
	private PrinterJob pJob;
	private Component comp;
	boolean scaleWidthToFit = true;

	public Imprimir(Component comp) {
		pFormat = new PageFormat();
		pJob = PrinterJob.getPrinterJob();
		this.comp = comp;
		printDialog();
	}

	private void printDialog() {
		if (pJob.printDialog()) {
			pJob.setPrintable(this, pFormat);
			try {
				pJob.print();
			} catch (PrinterException printerException) {
				System.out.println("Erro ao imprimir documento.");
			}
		}
	}

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

		double scale = 1.0;
		Graphics2D graphics2D;

		graphics2D = (Graphics2D) graphics;
		comp.setSize((int) pageFormat.getImageableWidth(), (int) pageFormat
				.getImageableHeight());
		comp.validate();

		if ((scaleWidthToFit)
				&& (comp.getMinimumSize().getWidth() > pageFormat
						.getImageableWidth())) {
			scale = pageFormat.getImageableWidth()
					/ comp.getMinimumSize().getWidth();
			graphics2D.scale(scale, scale);
		}

		graphics2D.setClip((int) (pageFormat.getImageableX() / scale),
				(int) (pageFormat.getImageableY() / scale), (int) (pageFormat
						.getImageableWidth() / scale), (int) (pageFormat
						.getImageableHeight() / scale));

		if (pageIndex > 0) {
			return Printable.NO_SUCH_PAGE;
		}

		graphics2D.translate(graphics2D.getClipBounds().getX(), graphics2D
				.getClipBounds().getY());

		comp.paint(graphics2D);
		return Printable.PAGE_EXISTS;

	}
}

Esse código eu fiz baseado em um código que eu encontrei na internet que possuía o seguinte cabeçalho:
/**

  • PrintMe is a class that lets you print documents on
  • the fly for free :wink: Printing in JDK 1.2 - 1.5 is hard.
  • With this, you just simply call it in your application
  • and add your text component like JTextPane:
  • new PrintMe().print(YourJTextComponent);
  • Reminder: Just make sure there is a text on your component :stuck_out_tongue_winking_eye:
  • Author : Jan Michael Soan
  • WebSite: http://www.jmsoan.com
  • Date : 04/17/2004
  • Time : 2:20 PM

*/

3 Respostas

Tamba

Para impressão da JTable, eu utilizei este código, e funciona normal.

http://www.guj.com.br/posts/list/17869.java

:thumbup:

J

Eu também tinha visto este código. Ele foi um dos que não imprimiu nada aqui. Assim como alguns outros que eu achei na internet, a impressora apenas puxava o papel, mas não imprimia nada, apesar de eu passar a JTable corretamente.

Tamba

Hoje eu utilizo este codigo, dei umas enchutada neles, e funciona perfeitamente no windows xp

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.JOptionPane;
import javax.swing.JTable;

/**
 * Classe que imprime uma JTable
 @author	Guilherme I. Keller
 */
public
class		ImprimirJTable
implements	Printable{
	private JTable tabela;
	private PrinterJob printerJob;
	private Graphics2D graphics2d;
	public static String nome_impressao = "Nome da Sua JTable";
	/**
	 * Metodo construtor da classe
         @param		tabela
         		Uma JTable a ser impressa
	 */
	public ImprimirJTable(JTable tabela){
		this.tabela	= tabela;
		printerJob = PrinterJob.getPrinterJob();
		printerJob.setPrintable(this);
		printerJob.setJobName(nome_impressao);
		if	(printerJob.printDialog())
		{
			try
			{
				printerJob.print();
			}
			catch	(PrinterException ex)
			{
				JOptionPane.showMessageDialog(	null,
						"Ocorreu um erro durante a impressão. \n"+ex.toString(),
						"Erro do Sistema",
						JOptionPane.ERROR_MESSAGE
				);
			}
		}
	}
	/**
	 * Metodo responsavel pela impressao da JTable
	 */
	public 
	int 		print(	Graphics g,
			PageFormat pageFormat,
			int pageIndex
	)
	throws	PrinterException{
		graphics2d = (Graphics2D) g;
		graphics2d.setColor(Color.black);
		int fontHeight = graphics2d.getFontMetrics().getHeight();
		// leave room for page number
		double pageHeight =	pageFormat.getImageableHeight()-fontHeight;
		double pageWidth = pageFormat.getImageableWidth();
		double tableWidth = (double) tabela.getColumnModel().getTotalColumnWidth();
		double scale = 1;
		if (tableWidth >= pageWidth){
			scale = pageWidth / tableWidth;
		}
		double headerHeightOnPage =	tabela.getTableHeader().getHeight()*scale;
		double tableWidthOnPage = tableWidth*scale;
		double oneRowHeight = (tabela.getRowHeight()+ tabela.getRowMargin())*scale;
		int numRowsOnAPage = (int) ((pageHeight-headerHeightOnPage)/oneRowHeight);
		double pageHeightForTable = oneRowHeight*numRowsOnAPage;
		int totalNumPages =	(int) Math.ceil(((double)tabela.getRowCount()) / numRowsOnAPage);
		if (pageIndex >= totalNumPages){
			return NO_SUCH_PAGE; //No more pages
		}
		graphics2d.drawString(nome_impressao, 10, 10);
		graphics2d.translate( pageFormat.getImageableX(),
				pageFormat.getImageableY()
		);
		graphics2d.translate( 0f,
				headerHeightOnPage
		);

		graphics2d.translate( 0f,
				-pageIndex*pageHeightForTable
		);
		// If this piece of the table is smaller than the size available,
		// clip to the appropriate bounds.
		if (pageIndex + 1 == totalNumPages){
			int lastRowPrinted = numRowsOnAPage * pageIndex;
			int numRowsLeft = tabela.getRowCount() - lastRowPrinted;
			graphics2d.setClip(	0,
					(int) (pageHeightForTable * pageIndex),
					(int) Math.ceil(tableWidthOnPage),
					(int) Math.ceil(oneRowHeight * numRowsLeft)
			);
		}
		// else clip to the entire area available.
		else{    
			graphics2d.setClip(	0,
					(int) (pageHeightForTable*pageIndex), 
					(int) Math.ceil(tableWidthOnPage),
					(int) Math.ceil(pageHeightForTable)
			);        
		}
		graphics2d.scale(scale, scale);
		tabela.paint(graphics2d);
		graphics2d.scale(1 / scale,	1 / scale);
		graphics2d.translate( 0f, pageIndex * pageHeightForTable);
		graphics2d.translate( 0f, -headerHeightOnPage);
		graphics2d.setClip(	0,	0,
				(int) Math.ceil(tableWidthOnPage), 
				(int) Math.ceil(headerHeightOnPage)
		);
		graphics2d.scale(scale, scale);
		tabela.getTableHeader().paint(graphics2d);	// paint header at top
		return Printable.PAGE_EXISTS;		// continues printing
	}
}

e chamo o método de outra classe assim:

new ImprimirJTable(Nome_da_JTable);
Criado 24 de janeiro de 2008
Ultima resposta 24 de jan. de 2008
Respostas 3
Participantes 2