14
Imprimindo com Java Java 2D Print API e Java Printing Service Uma visão geral das duas APIs de impressão do Java HERVAL FREIRE Em Java, o acesso aos recursos de impressão pode ser feito não por uma, mas por duas APIs complementares: a Java 2D Printing API ("Print API") e o Java Print Service (JPS). A Print API, teve sua primeira versão no JDK 1.1 e permite a manipulação e a impressão de textos e objetos gráficos. A JPS, que foi introduzida mais recentemente, no J2SE 1.4, traz facilidades para interação com filas de impressão inspirada no padrão Internet Printing Protocol (IPP). Inicialmente alvo de críticas por parte de muitos desenvolvedores devido às suas constantes mudanças desde a primeira versão, as APIs de impressão de Java hoje têm um bom grau de maturidade. A facilidade de utilizar a JPS para realizar tarefas como localizar e selecionar a impressora adequada ou imprimir arquivos fechados complementa a flexibilidade da Print API na formatação e organização de conteúdos gráficos para impressão. Este artigo apresenta uma visão geral dos vários recursos das duas APIs de impressão de Java, bem como ilustrar os seus modos de utilização mais comuns. Dada a flexibilidade de utilização, é comum encontrar-se frameworks que abstraem particularidades da API para atividades específicas (como a impressão de relatórios, do popular JasperReports ou a geração de PDF do iText, por exemplo). Este artigo não cobre a utilização de tais frameworks. Print API A Print API utiliza o mecanismo de desenho do Java 2D. Através de um objeto do tipo Graphics (ou sua subclasse, Graphics2D. A Graphics2D costuma ser mais utilizada na manipulação de objetos geométricos e transformação de coordenadas. No restante deste artigo, faremos referência apenas à Graphics2D), a aplicação renderiza o conteúdo a ser impresso, da mesma forma que é feito para exibir o conteúdo em um componente visual na tela. Dessa forma, qualquer informação que possa ser criada para visualização na tela pode também ser impressa.

Java Printing Service - Java Magazine

  • Upload
    herval

  • View
    6.033

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Java Printing Service - Java Magazine

Imprimindo com JavaJava 2D Print API e Java Printing ServiceUma visão geral das duas APIs de impressão do Java

HERVAL FREIRE

Em Java, o acesso aos recursos de impressão pode ser feito não por uma, mas por duas APIs complementares: a Java 2D Printing API ("Print API") e o Java Print Service (JPS). A Print API, teve sua primeira versão no JDK 1.1 e permite a manipulação e a impressão de textos e objetos gráficos. A JPS, que foi introduzida mais recentemente, no J2SE 1.4, traz facilidades para interação com filas de impressão inspirada no padrão Internet Printing Protocol (IPP). Inicialmente alvo de críticas por parte de muitos desenvolvedores devido às suas constantes

mudanças desde a primeira versão, as APIs de impressão de Java hoje têm um bom grau de maturidade. A facilidade de utilizar a JPS para realizar tarefas como localizar e selecionar a impressora adequada ou imprimir arquivos fechados complementa a flexibilidade da Print API na formatação e organização de conteúdos gráficos para impressão.Este artigo apresenta uma visão geral dos vários recursos das duas APIs de impressão de Java, bem

como ilustrar os seus modos de utilização mais comuns.

Dada a flexibilidade de utilização, é comum encontrar-se frameworks que abstraem particularidades da API para atividades específicas (como a impressão de relatórios, do popular JasperReports ou a geração de PDF do iText, por exemplo). Este artigo não cobre a utilização de tais frameworks.

Print APIA Print API utiliza o mecanismo de desenho do Java 2D. Através de um objeto do tipo Graphics

(ou sua subclasse, Graphics2D. A Graphics2D costuma ser mais utilizada na manipulação de objetos geométricos e transformação de coordenadas. No restante deste artigo, faremos referência apenas à Graphics2D), a aplicação renderiza o conteúdo a ser impresso, da mesma forma que é feito para exibir o conteúdo em um componente visual na tela. Dessa forma, qualquer informação que possa ser criada para visualização na tela pode também ser impressa. Para realizar a impressão com a Print API, devemos cumprir quatro etapas: 1. Criar uma job (tarefa) de impressão, representada por um objeto PrinterJob.2. Definir o conteúdo a ser impresso através dos métodos setPrintable() ou setPageable() do

PrinterJob.3. Opcionalmente, exibir um diálogo de configuração de impressão.4. Iniciar o processo chamando print() do PrinterJob.

Para que um objeto possa ser impresso, a sua classe deve implementar a interface Printable ou Pageable. Printable define um método de renderização print(), semelhante ao método paint() de componentes gráficos. A chamada a print() é feita pelo PrinterJob (como um callback), à medida que o sistema operacional solicita a impressão de páginas. A Tabela 1 resume os elementos da API. Páginas simples com PrintableConteúdos simples, como documentos de uma única página ou conjuntos de páginas sem variações

de layout (tamanho de papel, orientação etc.) podem ser implementados utilizando a interface Printable. Quando requisitado para imprimir um objeto Printable, o sistema de impressão faz chamadas sucessivas ao método print() do objeto, informando ao objeto o índice da página a ser impressa (que começa em zero). Assim, um objeto Printable pode imprimir um número arbitrário de páginas.

Nada obriga a impressão a iniciar da primeira página e páginas não precisam ser impressas em seqüência. O objeto Printable tem que ser capaz de lidar com “saltos” na numeração de páginas, e também com páginas que sejam impressas várias vezes seguidas, sem passar para uma página seguinte.

Page 2: Java Printing Service - Java Magazine

A Listagem 1 demonstra a impressão de um objeto Printable simples, que renderiza uma página somente. Note que o método print() retorna uma constante Printable.NO_SUCH_PAGE para informar ao PrinterJob que não existem mais páginas subseqüentes, permitindo que sistema encerre a tarefa de impressão.A Print API também permite exibir um diálogo de configuração para o usuário, como a seguir:

// Obtém um printerJobPrinterJob job = PrinterJob.getPrinterJob();// Exibe tela de configuração de pagina ao usuarioPageFormat pf = job.pageDialog(job.defaultPage());

As preferências selecionadas são armazenadas em um objeto PageFormat, que pode então ser associado aos objetos Printable ou Pageable a serem impressos.Documentos longos com PrintableObjetos Printable não dispõem de métodos para determinar o número de páginas a ser impresso.

Caso se deseje indicar previamente a quantidade de páginas, por exemplo para impressão eficiente em ordem reversa, é necessário usar objetos do tipo Pageable.

Pageable é voltada à gerência de documentos mais complexos, com uma quantidade pré-definida de páginas. Ela não define métodos de renderização de páginas. Cada página pode manter configurações próprias, em objetos PageFormat. Em linhas gerais, um objeto Pageable pode ser visto como um conjunto de objetos Printable de

tamanho definido, um para cada página.A Print API inclui uma implementação concreta da interface Pageable, a classe Book, que atende

aos requisitos da maior parte das aplicações que precisam imprimir documentos de várias páginas. A Listagem 2 demonstra a impressão de um documento de três páginas usando a classe Book.Antes do lançamento da JPS, o PrinterJob só era capaz de utilizar a impressora padrão do sistema,

sendo necessário mostrar um diálogo do sistema operacional, para que o usuário escolhesse a impressora. Com a introdução do JPS, a seleção de impressoras via programação se torna possível graças a PrinterServiceLookup.

Manipulando imagens e textos A impressão de imagens utilizando a Print API é simples: depois de se carregar a imagem, basta

chamar o método drawImage() da classe Graphics2D para posicioná-la na página. A Listagem 3 demonstra todos os passos da impressão de uma imagem JPEG.A impressão e organização de textos é uma tarefa um pouco mais complexa. A classe

LineBreakMeasurer permite manipular texto formatado e quebrar seu conteúdo em diversas linhas de largura definida. A quebra de sílabas é feita de acordo com as regras de internacionalização do locale em uso. Objetos TextLayout são utilizados para armazenar cada parágrafo (incluindo sua formatação), e para gerenciar a impressão de cada linha de texto no objeto Graphics2D.Cada objeto TextLayout armazena atributos de fonte, que podem ser utilizados para calcular o posicionamento do parágrafo e o espaçamento entre as linhas. A Figura 2, retirada do artigo “Printing in Java” (veja links) ilustra os atributos de fonte cobertos

pela API. São eles:§ Advance – distância entre o início de um bloco de texto e o final do último caractere.§ Ascent – distância entre o ponto superior direito do texto e a sua baseline.§ Baseline – linha de base do texto: uma posição relativa que depende da fonte em uso.§ Descent – distância entre o baseline e o ponto inferior da linha de texto.§ Leading – distância sugerida entre duas linhas utilizando-se uma determinada fonte, para que o

texto seja legível.

Todos esses atributos são acessíveis através de métodos getAtributo(), como getAdvance(), getBaseline(), etc. Além dos atributos de posicionamento, a formatação de outras características de um texto (como fonte, utilização de negrito ou itálico, etc) pode ser feita através do método addAttribute() da classe AttributedString.

// define a fonte de um AttributedString como Arial 12 AttributedString str = new AttributedString(“linha formatada”); str.addAttribute(TextAttribute.FONT, new Font("Arial", Font.ITALIC, 12));

Page 3: Java Printing Service - Java Magazine

É possível ainda formatar cada caractere de um AttributedString individualmente:

// define a fonte dos 3 primeiros caractered de um AttributedString como Arial 12 AttributedString str = new AttributedString(“linha mais ou menos formatada”); str.addAttribute(TextAttribute.FONT, new Font("Arial", Font.ITALIC, 12), 0, 3);

A Listagem 4 demonstra a utilização dos recursos para a impressão de texto formatado em múltiplas linhas. Uma vez criado um LineBreakMeasurer para o texto, solicita-se a impressão de cada parágrafo (chamando-se o método nextLayout()) até que não exista mais conteúdo a ser impresso. Cada parágrafo é instanciado como um objeto TextLayout. Observe que as classes LineBreakMeasurer e TextLayout não gerenciam a paginação de texto

automaticamente. Fica por conta do desenvolvedor efetuar esta paginação da forma que convier à sua aplicação, verificando o espaço restante na página. Alguns frameworks mais “alto nível” que utilizam a Print API executam esta lógica de paginação de forma transparente (como é o caso do JasperReports e do iText, por exemplo).

Apresentando o Java Print ServiceApesar do modelo utilizado pela Print API ser bastante útil para impressão de conteúdos gráficos

gerados pela aplicação, a Print API não fornece mecanismos para impressão de conteúdos streamed (como documentos PDF ou PostScript armazenados em arquivos, por exemplo).Com o JPS é usando um modelo de gerenciamento de conteúdo para impressão, que separa o

mecanismo de impressão da API Java 2D (diferente da Print API, que depende diretamente da Java 2D para funcionar). Esta separação de conceitos da JPS foi sugerida para permitir que, em futuras implementações, a JPS possa ser utilizada em ambientes que não dispõem da API gráfica Java 2D – como em dispositivos J2ME, por exemplo.O mecanismo de impressão é gerenciado por um objeto DocPrintJob. Os objetos que representam

documentos para impressão são representados pela interface Doc. Um Doc funciona como um tipo de “conversor de dados”, implementando métodos que são chamados pelo DocPrintJob para gerar a saída para a impressora. Tipos de documentos são identificados através de objetos DocFlavor, que representam um determinado tipo MIME de conteúdo – por exemplo, application/pdf, application/postscript e text/plain.A JPS inclui uma implementação da interface Doc, chamada SimpleDoc, capaz de manipular os

tipos MIME mais conhecidos sem necessidade de implementações adicionais. O SimpleDoc simplesmente carrega o documento e o envia para impressão, deixando o tratamento do conteúdo a cargo do sistema operacional. Por exemplo, um sistema Windows é capaz de imprimir diretamente um documento Word, se o MS Office estiver instalado, enquanto um sistema Linux será capaz de imprimir diretamente documentos PostScript devido à integração do Ghostscript com os serviços de impressão do Linux.A definição de atributos de impressão, documentos e impressoras é feitas através de objetos

AttributeSet. Há atributos específicos para formatação de documentos (DocAttributeSet), um job de impressão (PrintJobAttributeSet), requisições de impressão (i.e., um print job e todos os Docs associados a ele - PrintRequestAttributeSet) e impressora (PrintServiceAttributeSet). Para cada tipo de AttributeSet, a JPS define muitos atributos de configuração. O pacote

javax.print.attribute.standard inclui mais de 70 atributos, que permitem controlar desde a quantidade de cópias do documento até o nome que o processo deve receber na fila de impressão do sistema operacional. A utilização dos attribute sets é simples:

// Configura o conjunto de parametros para a impressora PrintRequestAttributeSet printerAttributes = new HashPrintRequestAttributeSet();

// Adiciona uma propriedade de impressão: imprimir 2 cópias printerAttributes.add(new Copies(2));

// Imprime o documento, utilizando o attribute set printJob.print(textDocument, printerAttributes);

A Tabela 2 resume alguns dos atributos disponíveis.

Page 4: Java Printing Service - Java Magazine

Descobrindo serviços de impressãoA localização de impressoras na JPS pode ser feita via programação. Além de escolher uma entre

todas as impressoras disponíveis, é possível fazer uma filtragem de dispositivos segundo uma série de critérios – por exemplo, impressoras com suporte a cores somente:

// localiza apenas as impressoras com suporte a cores AttributeSet attributes = new HashAttributeSet(); attributes.add(Chromaticity.COLOR);

PrintService[] pdfPrinters = PrintServiceLookup.lookupPrintServices(pdfFlavor, attributes);

O lookup (localização de impressoras) é feito através da classe PrintServiceLookup. A classe utiliza objetos DocFlavor para selecionar impressoras com suporte a tipos de documento específicos; também pode utilizar um conjunto de atributos, representado por um objeto PrintServiceAttributeSet. Os três métodos de localização são descritos na Tabela 3.Note que o serviço de localização da JPS pode ser usado também pela Print API sem dificuldades.

A Listagem 7 mostra um exemplo de impressão utilizando a Print API, que localiza a impressora a ser utilizada através dos métodos de lookup da JPS.

Imprimindo conteúdo com a JPSO processo de impressão com a JPS é tão simples quanto com a Print API. Uma vez definida a

impressora, cria-se um objeto Doc e agenda-se a impressão através de um DocPrintJob. Veja um exemplo na Listagem 6. É usado um parâmetro para definir se o conteúdo será impresso

usando os atributos definidos via programação ou se deverá ser exibida uma tela de configurações de impressão. No primeiro caso, o documento será enviado diretamente para a fila de impressão, sem confirmação por parte do usuário. Havendo a necessidade de se exibir um diálogo de configuração, pode-se fazê-lo através da classe ServiceUI (Figura 3), também do pacote javax.print. Ela permite ao usuário configurar a impressão, selecionar outra impressora e modificar o número de cópias, entre outras configurações. A Listagem 6 demonstra a utilização da ServiceUI.

ConclusõesAs APIs de impressão do Java evoluíram juntamente com a linguagem, ganhando recursos e

maturidade a cada release do JDK. Tratam-se de duas APIs bastante flexíveis e poderosas, que garantem ao desenvolvedor Java um alto grau de controle sobre a impressão de documentos dos mais variados tipos e formatos.

Linksjava.sun.com/products/java-media/2D/forDevelopers/sdk12print.htmlTutorial sobre o Java 2D Printing APIjava.sun.com/j2se/1.4.2/docs/guide/jpsJava Print Service User Guidejavaworld.com/javaworld/jw-10-2000/jw-1020-print.htmlPrinting in Javajcp.org/en/jsr/detail?id=6JSR-6 (Java Print Service) w3schools.com/media/media_mimeref.aspSobre tipos MIME

Herval Freire ([email protected]) é Sun Certified Java Programmer (SCJP), Web Components Developer (SCWCD), Micro Application Developer (SCMAD) e Sun Certified Architect (1) (SCEA). Atua como consultor em projetos Java EE e Java ME.

Tabela 1. Classes e interfaces da Print API (pacote java.awt.print) [interfaces em iálico]Paper Define as características físicas de uma página: largura, altura e área útil de

impressão (imageable area).PageFormat Define a orientação (landscape, portrait ou landscape reverso). Um

PageFormat também pode ser associado a um objeto Paper para a definição de outras características de tamanho de página.

PrinterJob Responsável pelo gerenciamento de impressões (incluindo exibição de diálogo de impressão e de configuração de página).

Book Implementa de forma simples a interface Pageable.

Page 5: Java Printing Service - Java Magazine

Pageable Define um conjunto de páginas, em que cada página pode ter configurações diferenciadas e ser renderizada por um objeto Printable diferente.

Printable Define o método de renderização de páginas, chamado pelo PrinterJob durante a impressão de um documento.

PrinterGraphics Permite à aplicação localizar o contexto gráfico do PrinterJob atualmente em execução.

Tabela 2. Seleção de atributos da JPS (pacote javax.print.attribute.standard)Chromaticity Atributo utilizado para definir a utilização de cores na impressão (ou impressão em preto e

branco). Usado também para localizar impressoras coloridas ou monocromáticas SheetCollate Modelo de separação de páginas em caso de múltiplas cópias (ou seja, o agrupamento de

páginas)PrintQuality Qualidade de impressãoMediaSize Dimensões do papel (ou outra mídia)Copies Número de cópias de um DocJobPriority Definições de prioridade da impressão na fila de impressão do sistema operacional

Tabela 3. Métodos da classe PrintserviceLookupPrintService lookupDefaultPrintService() Retorna a impressora definida como padrão pelo

sistema operacionalPrintService[] lookupPrintServices( DocFlavor flavor, AttributeSet attributes)

Retorna uma lista de todas as impressoras que suportam um determinado tipo de documento (DocFlavor) e/ou modelo de impressão (AttributeSet)

MultiDocPrintService[] lookupMultiDocPrintServices( DocFlavor[] flavors, AttributeSet attributes)

Retorna uma lista de impressoras com suporte aos diversos DocFlavors e ao AttributeSet especificados

Page 6: Java Printing Service - Java Magazine

Figura 2. atributos espaciais de um TextLayout

Figura 3. diálogo de impressão exibido pela JPS (classe ServiceUI)

Listagem 1. Imprimindo um objeto Printable

import java.awt.*;import java.awt.print.*;

public class PrintableExample { public PrintableExample() { // Obtem um job de impressao PrinterJob job = PrinterJob.getPrinterJob(); // Define o objeto a ser impresso job.setPrintable(new Desenho()); // exibe o dialogo de impressao. if (job.printDialog()) { try { // imprime o objeto printable job.print(); } catch (PrinterException e) { e.printStackTrace(); } } } public static void main(String[] args) { new PrintableExample(); }}

// definição de uma classe 'printable'

Page 7: Java Printing Service - Java Magazine

class Desenho implements Printable {

// Método de renderização de paginas public int print(Graphics graphics, PageFormat format, int pageIndex) throws PrinterException { // (caso o pageIndex seja maior que zero, retorna NO_SUCH_PAGE) if (pageIndex > 0) { return Printable.NO_SUCH_PAGE; } Graphics2D g2d = (Graphics2D) graphics; // desenha um retangulo na pagina int x = 85; int y = 87; g2d.draw(new Rectangle2D.Double(x, y, 400, 300)); // Indica que foi possível renderizar a página return Printable.PAGE_EXISTS; }}

Listagem 2. Imprimindo um objeto Pageable (Book)

import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.geom.Rectangle2D;import java.awt.print.*;

public class PageableExample { public PageableExample() { // Obtem um job de impressao PrinterJob job = PrinterJob.getPrinterJob(); // Define o objeto a ser impresso job.setPageable(new Livro()); // exibe o dialogo de impressao. if (job.printDialog()) { try { // imprime o objeto printable job.print(); } catch (PrinterException e) { e.printStackTrace(); } } } public static void main(String[] args) { new PageableExample(); }}

// definição de uma classe 'pageable' (um Book com 3 páginas)class Livro extends Book {

public Livro() { PageFormat formatoCapa = new PageFormat(); formatoCapa.setOrientation(PageFormat.PORTRAIT); PageFormat formatoPagina = new PageFormat(); formatoPagina.setOrientation(PageFormat.LANDSCAPE); // define o tamanho da pagina em 8,5x11 polegadas (Letter) // note que os valores tem que ser passados em pontos, // onde 1pt = 1/72 polegada formatoPagina.getPaper().setSize(612, 792); // Adiciona uma capa ao livro utilizando a formatação de capa append(new Capa(), formatoCapa); // Adiciona duas paginas ao livro utilizando a formatacao de pagina interna append(new Pagina(), formatoPagina); append(new Pagina(), formatoPagina); System.out.println("Livro criado. Total de paginas: " + getNumberOfPages()); } }

// Renderiza a capa: um retangulo ao redor da area util da paginaclass Capa implements Printable {

Page 8: Java Printing Service - Java Magazine

public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException { if (pageIndex > 1) { return Printable.NO_SUCH_PAGE; } g.drawRect((int) pageFormat.getImageableX()+1, (int) pageFormat.getImageableY()+1, (int) pageFormat.getImageableWidth()-2, (int) pageFormat.getImageableHeight()-2); return Printable.PAGE_EXISTS; } }

// Renderiza uma pagina do livro: apenas um texto impresso no meio da paginaclass Pagina implements Printable {

public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException { // Imprime somente os indices 0 e 1 if (pageIndex > 2) { return Printable.NO_SUCH_PAGE; } g.drawString("JavaMagazine", (int) pageFormat.getImageableWidth()/3, (int) pageFormat.getImageableHeight()/2); return Printable.PAGE_EXISTS; } }

Listagem 3: imprimindo imagens

import java.awt.*;import java.awt.print.*;

public class ImagePrintExample implements Printable { String imagem = "severina.jpg"; public ImagePrintExample() { // Obtem um job de impressao PrinterJob job = PrinterJob.getPrinterJob(); // Define o objeto a ser impresso job.setPrintable(this); // exibe o dialogo de impressao. if (job.printDialog()) { try { // imprime o objeto printable job.print(); } catch (PrinterException e) { e.printStackTrace(); } } } public int print(Graphics g, PageFormat format, int page) throws PrinterException { if (page != 0) { return NO_SUCH_PAGE; } Graphics2D gr = (Graphics2D) g; // posiciona o objeto graphics no começo da area util da pagina gr.translate(format.getImageableX(), format.getImageableY());

// carrega a imagem do arquivo jpg Image image = Toolkit.getDefaultToolkit().getImage(imagem); MediaTracker mediaTracker = new MediaTracker(new Container()); mediaTracker.addImage(image, 0); try { mediaTracker.waitForID(0); } catch (InterruptedException e) { e.printStackTrace(); } // imprime a imagem na posicao relativa 10, 10 gr.drawImage(image, 10, 10, null); return PAGE_EXISTS; }

Page 9: Java Printing Service - Java Magazine

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

Listagem 4. Impressão de texto formatado em múltiplas linhas

import java.awt.*;import java.awt.font.*;import java.awt.print.*;import java.io.*;import java.text.AttributedString;import java.util.ArrayList;import java.util.Iterator;

public class AdvancedTextExample implements Printable { // array de paragrafos do texto ArrayList texto; public AdvancedTextExample() throws IOException { // Obtem um job de impressao PrinterJob job = PrinterJob.getPrinterJob(); // carrega o texto a ser impresso BufferedReader re = new BufferedReader(new FileReader("texto.txt")); texto = new ArrayList(); String line = re.readLine(); while (line != null) { texto.add(line); line = re.readLine(); } re.close(); // Define o objeto a ser impresso job.setPrintable(this); // exibe o dialogo de impressao. if (job.printDialog()) { try { // imprime o objeto printable job.print(); } catch (PrinterException e) { e.printStackTrace(); } } } public int print(Graphics g, PageFormat format, int page) throws PrinterException { if (page != 0) { return NO_SUCH_PAGE; } Graphics2D gr = (Graphics2D) g;

// determina o ponto de inicio do texto (inicio da area util + 10 pontos) float posX = (float) format.getImageableX()+10; float posY = (float) format.getImageableY()+10;

// determina a largura do texto como 350 pontos (dpi) float larguraTexto = 350;

// para cada paragrafo, imprime o paragrafo formatado Iterator it = texto.iterator(); while (it.hasNext()) { String line = (String) it.next(); // caso haja uma linha em branco, substituir por um espaço // para permitir formatação if (line.length() == 0) { line = " "; } // texto formatado a ser impresso AttributedString str = new AttributedString(line); // define a fonte do texto como arial 12 itálico

Page 10: Java Printing Service - Java Magazine

str.addAttribute(TextAttribute.FONT, new Font("Arial", Font.ITALIC, 12));

// instancia um line breaker para o texto formatado LineBreakMeasurer quebrador = new LineBreakMeasurer(str.getIterator(), gr.getFontRenderContext()); // cria um TextLayout para armazenar cada linha 'quebrada' TextLayout linha = quebrador.nextLayout(larguraTexto); while (linha != null) { // posiciona o texto posY += linha.getAscent();

linha.draw(gr, posX, posY); // soma espaço para a próxima linha posY += linha.getDescent() + linha.getLeading();

linha = quebrador.nextLayout(larguraTexto); } } // fim dos paragrafos return PAGE_EXISTS; }

public static void main(String[] args) { try { new AdvancedTextExample(); } catch (IOException e) { System.out.println("Erro imprimindo: " + e.getMessage()); } }}

Listagem 5. Exemplos de utilização do serviço de lookup

import javax.print.*;import javax.print.attribute.*;

public class LookupExample { public LookupExample() { // Localiza a impressora padrão PrintService printService = PrintServiceLookup.lookupDefaultPrintService(); System.out.println("Impressora padrão: " + printService.getName()); // Localiza todas as impressoras disponíveis no sistema (inclusive impressoras em rede) PrintService[] printers = PrintServiceLookup.lookupPrintServices(null, null); for (int i = 0; i < printers.length; i++) { System.out.println(printers[i].getName()); } // Localiza todas as impressoras com suporte a impressão de PDFs e com suporte a cores DocFlavor pdfFlavor = DocFlavor.BYTE_ARRAY.PDF; AttributeSet attributes = new HashAttributeSet(); attributes.add(Chromaticity.COLOR);

PrintService[] pdfPrinters = PrintServiceLookup.lookupPrintServices(pdfFlavor, attributes); for (int i = 0; i < pdfPrinters.length; i++) { System.out.println(pdfPrinters[i].getName()); } } public static void main(String[] args) { new LookupExample(); }}

Listagem 6. Imprimindo duas cópias de um arquivo texto

import java.io.FileInputStream;import java.io.FileNotFoundException;import javax.print.*;import javax.print.attribute.*;

public class JpsPrintExample { public JpsPrintExample(boolean showDialog) { try { // Localiza todas as impressoras com suporte a arquivos txt PrintService[] printerServices = PrintServiceLookup.lookupPrintServices( DocFlavor.INPUT_STREAM.AUTOSENSE, null);

Page 11: Java Printing Service - Java Magazine

System.out.println("Impressoras com suporte: " + printerServices.length); // Localiza a impressora padrão PrintService printer = PrintServiceLookup.lookupDefaultPrintService(); System.out.println("Impressora: " + printer.getName()); System.out.println("Imprimindo arquivo txt"); // Definição de atributos do conteúdo a ser impresso: DocFlavor docFlavor = DocFlavor.INPUT_STREAM.AUTOSENSE; // Atributos de impressão do documento HashDocAttributeSet attributes = new HashDocAttributeSet(); // InputStream apontando para o conteúdo a ser impresso FileInputStream fi = new FileInputStream("teste.txt"); // Cria um Doc para impressão a partir do arquivo exemplo.txt Doc textDocument = new SimpleDoc(fi, docFlavor, attributes); // Configura o conjunto de parametros para a impressora PrintRequestAttributeSet printerAttributes = new HashPrintRequestAttributeSet(); if (showDialog) { // exibe um dialogo de configuracoes de impressao PrintService service = ServiceUI.printDialog(null, 320, 240, printerServices, printer, docFlavor, printerAttributes);

if (service != null) { DocPrintJob printJob = service.createPrintJob(); printJob.print(textDocument, printerAttributes); } } else { // Cria um job de impressão DocPrintJob printJob = printer.createPrintJob(); // Adiciona uma propriedade de impressão: imprimir 2 cópias printerAttributes.add(new Copies(2)); // Imprime o documento sem exibir uma tela de dialogo printJob.print(textDocument, printerAttributes); } } catch (FileNotFoundException ex) { System.out.println("Arquivo teste.txt não encontrado!"); } catch (PrintException ex2) { System.out.println("Erro de impressão: " + ex2.getMessage()); } } public static void main(String[] args) { new JpsPrintExample(true); }}

Listagem 7. Localizando impressora com a JPS e imprimindo um objeto Printable

import java.awt.*;import java.awt.geom.Rectangle2D;import java.awt.print.*;

public class JpsPrintableExample { public JpsPrintableExample() { PrintService service = null;

// JPS: Localiza todas as impressoras disponíveis // no sistema (inclusive impressoras em rede) PrintService[] printers = PrintServiceLookup.lookupPrintServices(null, null);

// JPS: seleciona a última impressora disponível service = printers[printers.length-1];

// Obtem um job de impressao PrinterJob job = PrinterJob.getPrinterJob(); try { // Define que o printer job vai utilizar a // impressora localizada pela JPS job.setPrintService(service); } catch (PrinterException e1) {

Page 12: Java Printing Service - Java Magazine

System.out.println("Erro acessando impressora: " + e1.getMessage()); } // Define o objeto a ser impresso job.setPrintable(new Desenho()); // exibe o dialogo de impressao. if (job.printDialog()) { try { // imprime o objeto printable job.print(); } catch (PrinterException e) { e.printStackTrace(); } } } public static void main(String[] args) { new PrintableExample(); }}