Uno degli aspetti più oscuri di Java è quello della stampa. In questo articolo vedremo come è possibile stampare in Java attraverso un semplice esempio di writer che ci permetterà di stampare un testo inserito in una TextArea in una o piu pagine

Gli strumenti

Un delle novità relative allAWT del JDK1.1 è la possibilità di utilizzare la stampante. La difficoltà principale nella creazione di questi strumenti è ovviamente quello di non violare la caratteristica principale di Java: la portabilità. Bisogna creare delle API che permettano il richiamo alle risorse locali relative alla stampa. Nel JDK1.1 lobiettivo e stato raggiunto definendo un nuovo oggetto del package java.awt cioè loggetto PrintJob. Esso rappresenta loggetto attraverso cui si ha accesso alle risorse locali relative allutilizzo della stampante. Per ottenere un oggetto PrintJob si utilizza il seguente metodo della classe Toolkit:

PrintJob getPrintJob(Frame frame, String title,Properties prop);

Questo metodo permetterà la visualizzazione della Dialog per linserimento dei parametri relativi alla stampa. Questo in dipendenza della piattaforma. I limiti di sicurezza nellaccedere a risorse locali sono regolati del SecurityManager attivo in quel momento. Nel caso di Applet (untrusted) non sarà quindi possibile utilizzare tali classi. Nel caso di Windows si otterrà la Dialog di figura 1.

Figura 1

Il precedente metodo della classe Toolkit ha tre parametri:

  • frame : quando si richiama il metodo getPrintJob() si ha la visualizzazione di una Dialog per cui è necessario specificare il frame padre.
  • title : rappresenta il titolo della finestra di dialog che sarà visualizzata. In Windows95 non appare.
  • prop : rappresenta un oggetto di tipo Properties che permette di assegnare particolari parametri relativi alla stampa od alla Dialog di visualizzazione.

Un volta visualizzata la Dialog e scelti i parametri relativi alla stampa, bisognerà fornire un meccanismo per i dati da stampare. Il JDK1.1 fornisce a tale scopo linterfaccia java.awt.PrintGraphics. Questa interfaccia prevede la definizione del solo metodo getPrintJob() ma la cosa importante è che essa è implementata dalloggetto Graphics che conterrà tutto quello che verrà stampato. Quindi, una volta creato loggetto PrintJob dovremo ottenere da esso loggetto di tipo Graphics (che implementa PrintGraph) su cui inserire tutto quello che vorremmo stampare.

Attraverso il metodo getGraphics() delloggetto PrintJob otterremo un oggetto di tipo Graphics che rappresenterà il contenuto di una pagina di stampa. Tutto quello che scriveremo su questo oggetto sarà stampato su una stessa pagina non appena chiameremo il suo metodo dispose(). Nel caso in cui volessimo stampare su unaltra pagina non dovremo fare altro che richiamare un altro oggetto Graphics con il metodo getGraphics(). Questo non prima di aver eseguito la dispose(). Per chiudere il processo di stampa basterà richiamare il metodo end() del PrintJob. La classe PrintJob dispone anche di metodi che forniscono informazioni relativi alle dimensioni delle pagine ed alla loro risoluzione:

Dimension getPageDimension();

int getPageRisolution();

Questi metodi sono comunque utilizzati in casi particolari che non tratteremo.

Vediamo di riassumere brevemente il procedimento di stampa:

1. Da un oggetto di tipo Toolkit si ottiene loggetto di tipo PrintJob attraverso il metodo getPrintJob() settando le eventuali proprietà. 2. Verrà visualizzata una Dialog caratteristica dellambiente, per linserimento dei dati relativi alla stampa. 3. Un volta inseriti i dati e dato conferma, si otterrà un oggetto di tipo Graphics dal PrintJob attraverso il metodo getGraphics(). 4. Si agirà su questo oggetto attraverso i metodi caratteristici dello stesso per disegnare o scrivere testo. 5. Si chiamerà il metodo dispose() per inviare alla stampante i dati relativi alla pagina da stampare. 6. Nel caso si volessero altre pagine si ritorna al passo 3. 7. Finita la stampa si chiude loggetto PrintJob attraverso il metodo end().

Stampa di componenti

Il JDK1.1 fornisce altri due strumenti che facilitano la stampa di determinati componenti. Questo si ottiene attraverso due nuovi metodi della classe Component :

  • print(g) : permette la stampa del componente nella pagina relativa alloggetto di tipo Graphics g inserito come parametro.
  • printAll(g) : permette la stampa del componente, e di tutti i componenti in esso contenuti, nella pagina relativa alloggetto di tipo Graphics g inserito come parametro.

I metodi print() e printAll() ( che non fa altro che richiamare il primo per ogni componenti contenuto nel precedente) sono definiti in modo particolare per ognuno dei componenti standard di Java. Per esempio richiamare il metodo print() di una TextArea significa stampare il testo in essa contenuto, mentre applicarlo ad un Button significa stampare il disegno del Button. Questo lo potremo verificare nellesempio che seguirà.

In Pratica?

A parte tutte le parole dette in pratica il procedimento è molto semplice e lo esamineremo attraverso il listato relativo alla creazione di una piccola macchina da scrivere. Costruiremo una TextArea che ci permetterà di stampare il contenuto in una o più pagine. Per dividere le varie pagine utilizzeremo un separatore che potremo inserire attraverso la pressione di un tasto. Oltre a questo pulsante ne avremo uno per il reset della TextArea ed altri due decisamente più importanti nel nostro contesto. Il primo si chiama Print e permetterà la stampa del solo contenuto della TextArea diviso nelle pagine scelte, mentre il secondo PrintAll ci permetterà di stampare il tutto ovvero tutto il Frame attraverso il metodo printAll(). Noteremo che nel primo caso si avrà la stampa solamente del contenuto della TextArea mentre nel secondo caso avremo la stampa di tutto il contenuto del frame compresi i pulsanti. In questo secondo caso la TextArea non apparirà come componente ma permetterà la stampa del suo contenuto a dimostrazione del fatto che il richiamo alla printAll() non è altro che un richiamo ripetuto ai print() di tutti i componenti relativi ad un Container.

Il programma si compone di varie parti ma la principale è costituita dal metodo gestisci_stampa() che permette di stampare il contenuto degli oggetti inseriti nei modi scelti.

Inizialmente acquisiamo il Toolkit di default e poi creiamo loggetto PrintJob. A questi punto se iil valore di ritorno non è null (caso in cui si verificassero dei problemi), inizieremo la stampa. La variabile tutto è boolean e ci dice se è stato premuto il pulsante Print (tutto=false) o il pulsante PrintAll (tutto=true). Nel caso in cui avessimo premuto Print non faremo altro che dividere il contenuto della TextArea txa_input (dove inseriremo il testo da stampare) in varie parti ciascuna rappresentante una pagina. Assegneremo ciascuna pagina allo stesso componente, otterremo loggetto Graphics dal PrintJob ed lo utilizzeremo come argomento del metodo print. A questo punto manderemo i dati alla stampante attraverso il metodo dispose(). Ripeteremo il procedimento per ogni token-pagina e finiremo ripristinando il vecchio valore nella TextArea e chiudendo la sessione di stampa con il metodo end(). Potrebbe stupire il procedimento di salvataggio del contenuto della TextArea e della assegnazione ad essa del teso relativo ad ogni pagina prima della stampa. Questo si è reso necessario per il fatto che se il contenuto del componente da stampare non è visibile, non si ha la stampa dello stesso. Si ha un funzionamento simile a quello relativo alle immagini. Fino a che non si fa la paint non si dispone del contesto grafico. Qui è necessario che il Component sia visibile e quindi inserito nel Layout con una add().

Conclusioni

Abbiamo quindi visto come si gestisce la stampa in Java attraverso gli nuovi strumenti offerti dal JDK1.1. Noi abbiamo visto questo procedimento nel caso di componenti quali TextField e Button ma sarebbe curioso vedere cosa accade nel caso di un Canvas. In questo caso si avrebbe, infatti, la stampa relativa al suo contenuto grafico. Potrebbe essere un utile esercizio quello di disporre, la classe creata in questo esempio, di una zona grafica su cui disegnare.