MokaByte Numero 10 - Luglio 1997
Foto
La stampa in Java 
 
di
Massimo Carli
Vediamo come risolvere un problema apparentemente impossibile

 


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 all’AWT 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 l’obiettivo e’ stato raggiunto definendo un nuovo oggetto del package java.awt cioè l’oggetto PrintJob. Esso rappresenta l’oggetto attraverso cui si ha accesso alle risorse locali relative all’utilizzo 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 l’inserimento dei parametri relativi alla stampa. Questo in dipendenza della piattaforma. I limiti di sicurezza nell’accedere 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:

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 l’interfaccia java.awt.PrintGraphics. Questa interfaccia prevede la definizione del solo metodo getPrintJob() ma la cosa importante è che essa è implementata dall’oggetto Graphics che conterrà tutto quello che verrà stampato. Quindi, una volta creato l’oggetto PrintJob dovremo ottenere da esso l’oggetto di tipo Graphics (che implementa PrintGraph) su cui inserire tutto quello che vorremmo stampare.

Attraverso il metodo getGraphics() dell’oggetto 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 un’altra 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 l’oggetto di tipo PrintJob attraverso il metodo getPrintJob() settando le eventuali proprietà.
  2. Verrà visualizzata una Dialog caratteristica dell’ambiente, per l’inserimento 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 l’oggetto 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 :

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 nell’esempio 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 l’oggetto 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 l’oggetto 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.
 

  

 

MokaByte rivista web su Java

MokaByte ricerca nuovi collaboratori
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it