PDA

View Full Version : [JAVA] Stampare direttamente sulla stampante


franksisca
14-06-2009, 20:41
devo stampare delle cartoline di auguri ad un elenco di clienti che ho nel mio archivio....e volevo fare una classse che mandasse instampa autoameticamente il tutto.

come posso fare?

PGI-Bis
15-06-2009, 13:12
Crei una classe che concretizza Printable e disegna i dati del cliente su una cartolina. Prendi Book, aggiungi uno dei tuoi Printable per ogni cartolina, lo passi a PrinterJob (setPageable) e con un print() stampi il tutto.

franksisca
15-06-2009, 13:27
Crei una classe che concretizza Printable e disegna i dati del cliente su una cartolina. Prendi Book, aggiungi uno dei tuoi Printable per ogni cartolina, lo passi a PrinterJob (setPageable) e con un print() stampi il tutto.

si avevo letto della classse printable...ma non mi "chiarisco" come settare le dimensioni della cartolina....poi siccome dovrei stampare da un lato indirizzo e dall'altro messaggio.....comesetto le dimesnioni???

Book sarebbe??? è un calasse???

ora cerco nelle api in attesa di una tua risposta :D

PGI-Bis
15-06-2009, 13:40
Book è una classe e serve per "impilare" più oggetti Printable in modo da mandare in stampa tutto quanto in un blocco, eventualmente con dimensioni di pagina diverse.

Le dimensioni della cartolina puoi impostarle come dimensioni di pagina (PageFormat) tramite il PrinterJob o puoi frazionare una pagina A4 in stampando più cartoline su un solo modulo.

Se hai delle cartoline in bianco da mettere nella stampante allora usi PageFormat. Se invece devi "ritagliarle" dopo averle stampate allora usi come formato pagina la dimensione del foglio e stampi più cartoline con un solo Printable.

Per quanto riguarda il fronte-retro bisogna vedere le la stampate lo supporta fisicamente o no. In caso affermativo è sufficiente far stampare al Printable due pagina anzichè una: la prima disegna la parte anteriore, la seconda la posteriore.

Altrimenti devi definire un Printable per la parte anteriore e uno per la posteriore. Stampi, giri la carta, stampi, fine. Il problema di questo tipo di stampa è che se la stampate prende due fogli in una volta sola (cosa tutt'altro che rara) mandi a quel paese tutte le pagine successive.

franksisca
15-06-2009, 13:51
o non ho capito o non sono stato chiaro:


la cartolina che devo stampare è tipo "questa":

http://www.unostudioinholmes.org/firenze2007/cartolina.jpg


solo che a volte i dati per l'indirizzo sono a sinistra e a volte a destra.

io da software volevo fare un qualcosa del genere:

scelgo l'ìelenco dei contatti a cui devo mandare le cartoline (oggetto contatto con tutti i dati all'interno) selezione se l'idirizzo è a destra o sinistra, e mando in stampa.


nella stampante metto le 50 cartoline (numero indicativo) e lui me le compila da solo.

allora per settare il formato della cartolina posso usare il pageFormata (che unità di misura usa???), ma per dirgli a "che altezza" stampare indirizzi e messaggi???
uso delle misure in pixel tipo
print ("indirizzo amico", verticeSinistroAltoX,verticeSinistroAltoY,altezza,larghezza)
oppure devo usare altro?


sò che le cartoline sono tutte diverse, infatti prevedo la scelta della "struttura" in questo modo (vorrei) :
indirizzo dx alto-medio-basso e idem per sinistra

PGI-Bis
15-06-2009, 14:17
altezza e larghezza della cartolina la incapsuli in un PageFormat, da impostare come formato di pagina per il PrinterJob.

La posizione degli elementi la stabilisci nel metodo print del printable. Nel metodo print usi il PageFormat per stabilire l'ampiezza della superficie effettivamente stampabile: la cartolina può essere di 10x7 cm ma non è detto che la stampante possa occupare fisicamente tutta quell'era (alcune hanno un margine di stampa minimo ma rilevante).

Personalmente ritengo sempre conveniente usare un approccio "percentuale" alla stampa, cioè calcoli la posizione degli elementi in proporzione all'altezza e larghezza dell'area stampabile il che ti garantisce una certa indipendenza dalle peculiarità della stampente.

Volendo adottare un approccio assoluto, un punto nel Graphics del Printable corrisponde a 0.35 millimetri sul foglio.

banryu79
15-06-2009, 14:19
Volendo adottare un approccio assoluto, un punto nel Graphics del Printable corrisponde a 0.35 millimetri sul foglio.

Si sa perchè è così?

PGI-Bis
15-06-2009, 14:23
Ce lo dicono le API (PageFormat).

banryu79
15-06-2009, 14:43
Ce lo dicono le API (PageFormat).
Ci mancherebbe (mica pensavo che fosse il risultato empirico di una tua effettiva misurazione :D), io intendevo se si conosce il motivo per cui è stata fatta questa scelta (cioè è stata scelta proprio la misura di 0.35 mm) dagli implementatori.
Ok, è OT.

PGI-Bis
15-06-2009, 14:50
Il settataduesimo di pollice (che corrisponde ai predetti millimetri per chi usi il sistema metrico decimale al posto di mani, piedi, pertiche e così via) salta fuori da qualche standard ma ora come ora non ricordo quale.

banryu79
15-06-2009, 15:24
Il settataduesimo di pollice (che corrisponde ai predetti millimetri per chi usi il sistema metrico decimale al posto di mani, piedi, pertiche e così via) salta fuori da qualche standard ma ora come ora non ricordo quale.
Ok grazie, vado a soddisfare le mie curiosità da gugle.

franksisca
15-06-2009, 16:00
pgi a volte mi fai paura...per curiosità....ma tutta farina del tuo sacco (quindi appassionato) o ti ci ha portato la vita (lavoro/scuola)

PGI-Bis
15-06-2009, 16:58
E' tutta farina di sacchi altrui: leggi di qua, leggi di là, alla fine te le ricordi.

franksisca
15-06-2009, 21:31
E' tutta farina di sacchi altrui: leggi di qua, leggi di là, alla fine te le ricordi.

ok...quindi sei un appassionato che lavora "nel suo campo"....GG a te :D

franksisca
10-07-2009, 16:25
altezza e larghezza della cartolina la incapsuli in un PageFormat, da impostare come formato di pagina per il PrinterJob.

La posizione degli elementi la stabilisci nel metodo print del printable. Nel metodo print usi il PageFormat per stabilire l'ampiezza della superficie effettivamente stampabile: la cartolina può essere di 10x7 cm ma non è detto che la stampante possa occupare fisicamente tutta quell'era (alcune hanno un margine di stampa minimo ma rilevante).

Personalmente ritengo sempre conveniente usare un approccio "percentuale" alla stampa, cioè calcoli la posizione degli elementi in proporzione all'altezza e larghezza dell'area stampabile il che ti garantisce una certa indipendenza dalle peculiarità della stampente.

Volendo adottare un approccio assoluto, un punto nel Graphics del Printable corrisponde a 0.35 millimetri sul foglio.mi espliciti questo per favore :D

PGI-Bis
10-07-2009, 17:23
Banalmente se devi stampare un nome ed un cognome in un certo campo di una scheda calcoli la posizione del campo sulla scheda in ragione di una percentuale dell'altezza e della larghezza della pagina. Dopodichè estrai le coordinate applicando quella percentuale alla superficie della pagina nel metodo print. La cosa da una sua flessibilità alla stampa e ti permette di adattare rapidamente il codice ad eventuali cambiamenti nelle dimensioni della scheda.

Parlo naturalmente di stampa di moduli. Per disegni et similia uno usa le coordinate del disegno, eventualmente in scala.

franksisca
10-07-2009, 18:58
Banalmente se devi stampare un nome ed un cognome in un certo campo di una scheda calcoli la posizione del campo sulla scheda in ragione di una percentuale dell'altezza e della larghezza della pagina. Dopodichè estrai le coordinate applicando quella percentuale alla superficie della pagina nel metodo print. La cosa da una sua flessibilità alla stampa e ti permette di adattare rapidamente il codice ad eventuali cambiamenti nelle dimensioni della scheda.

Parlo naturalmente di stampa di moduli. Per disegni et similia uno usa le coordinate del disegno, eventualmente in scala.

e ora ti faccio la domandina cacaxxxxxo


siccome dovrò scrivere
Nome Cognome
Indirizzo
Comune(PROVINCIA)


come posso calcolare le lunghezze di questi caratteri???

tipo se l'indirizzo è troppo lungo e voglio spezzarlo su 2 righe, come faccio?

PGI-Bis
10-07-2009, 19:17
Puoi usare LineBreakMeasurer. Gli dai in pasto il testo che vuoi disegnare dopodichè gli passi lo spazio orizzontale in cui vuoi disegnare quel testo e lui ti restituisce tanti TextLayout quante sono le linee risultati. Se il testo occupa una sola riga in quello spazio avrai un solo TextLayout, altrimenti ne otterrai più d'uno. C'è un esempio nella javadoc che dice tutto e di più al riguardo.

Oceans11
10-07-2009, 19:31
Assolutamente OT:

cazzarola PGI!!!!
secondo me tu ci nascondi un sistema ultra avanzato di question aswering!!
oppure conosci tutta la documentazione a memoria :D
Fenomenale!

PGI-Bis
10-07-2009, 19:35
la seconda che hai detto.

ndakota
10-07-2009, 20:06
tra i motivi per scegliere java si può considerare tranquillamente il vantaggio di ricevere, eventualmente, aiuto da PGI-bis :O

franksisca
10-07-2009, 20:08
tra i motivi per scegliere java si può considerare tranquillamente il vantaggio di ricevere, eventualmente, aiuto da PGI-bis :O

http://www.dduniverse.net/ita/images/smilies/flag_of_truce.gif

franksisca
11-07-2009, 08:47
allora questo è il main che sto provando:
Paper paper = new Paper();
paper.setSize(5, 2);// setto la dimensione in punti del foglio un
// punto nel Graphics del Printable corrisponde
// a 0.35 millimetri sul foglio.
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);

PaginaStampante ps = new PaginaStampante();// crea l'oggetto che si
// occupera della stampa e
// che quindi deve contenere
// le liste dei clienti
ps.setPageFormat(pageFormat);// setto il pageformat....EVENTUALMETNE
// potremmo sceglierlo da software

PrinterJob pj = PrinterJob.getPrinterJob();// oggetto che si occupa
// della stampa vera e
// propria
pj.printDialog();// se commentato parte instant la stampa altrimenti
// parte il dialog per aggiungere più documenti alla coda di stampa si
// utilizza la classe book

pj.setPrintable(ps);
pj.print();// stampa


e questa è la classe che implementa printable

package view;

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

public class PaginaStampante implements Printable {

private PageFormat pageFormat;

@Override
public int print(Graphics g, PageFormat pagina, int pageIndex)
throws PrinterException {
if (pageIndex > 0)
return NO_SUCH_PAGE;
g.drawRect(
(int) this.pageFormat.getImageableX(),
(int) this.pageFormat.getImageableY(),
(int) this.pageFormat.getImageableWidth(),
(int) this.pageFormat.getImageableHeight());

return PAGE_EXISTS;
}

public void setPageFormat(PageFormat pageFormat) {
this.pageFormat = pageFormat;
}

}



come potete vedere la banalità e di casa.

solo che qualsiasi valore metto al paper.setSize(5, 2); mi disegna un rettangolo sempre uguale.

tralascio qualche cosa?

P.S.: 5,2 sono valori indicativi, per avere una cartolina 10*7 dovrei mettere 29*20

franksisca
13-07-2009, 09:50
aggiungo che ho inserito questo

System.out.println("get i x " + this.pageFormat.getImageableX ());
System.out.println("get i x " + this.pageFormat.getImageableY ());
System.out.println("getx: " + this.pageFormat.getImageableWidth() );
System.out.println("getx: " + this.pageFormat.getImageableHeight() );



e mi stampa questo
get i x 72.0
get i x 72.0
getx: 468.0
getx: 648.0
get i x 72.0
get i x 72.0
getx: 468.0
getx: 648.0

ora chi mi spiega il perchè?

PGI-Bis
13-07-2009, 16:35
Trascurando per un attimo il classico "non si fa così", imposti le dimensioni del foglio ma non l'area stampabile che resta quella precotta. Devi usare setImageableArea se vuoi alterare i valori dell'area stampabile.

franksisca
13-07-2009, 17:22
Trascurando per un attimo il classico "non si fa così", imposti le dimensioni del foglio ma non l'area stampabile che resta quella precotta. Devi usare setImageableArea se vuoi alterare i valori dell'area stampabile.

fatto....ho provato con set are con valori 0,0, 5,2 (stessi del setsize), ma niente.


cosa non si fà così?

banryu79
13-07-2009, 17:34
Prova a vedere se questa lettura (http://java.sun.com/docs/books/tutorial/2d/printing/index.html) aiuta a dipanare qualche dubbio circa il "come fare" ;)

franksisca
17-07-2009, 15:41
con questo codice:
package core;

import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.Vector;

public class CreazioneStampa {

private Paper paper;
private PageFormat pageFormat;
private PaginaStampante paginaStampante;
private Vector<Cliente> clienti;
private String messaggio;
private int larghezza, altezza;

public CreazioneStampa(Vector<Cliente> clienti, String messaggio) {
this.messaggio = messaggio;
this.clienti = clienti;
this.paper = new Paper();
this.pageFormat = new PageFormat();
this.paginaStampante = new PaginaStampante();
}

public void stampa() throws PrinterException {
this.paper.setSize(this.larghezza, this.altezza);
this.paper.setImageableArea(20, 20, this.larghezza, this.altezza);
this.pageFormat.setPaper(this.paper);
this.paginaStampante.setPageFormat(this.pageFormat);
this.paginaStampante.setMessaggio(this.messaggio);

for (int i = 0; i < this.clienti.size(); ++i) {
this.paginaStampante.setClienti(this.clienti.get(i));
PrinterJob pj = PrinterJob.getPrinterJob();
pj.printDialog();// da commentare
pj.defaultPage(this.pageFormat);
pj.setPrintable(this.paginaStampante);
pj.print();
}
}

public int getLarghezza() {
return this.larghezza;
}

public void setLarghezza(int larghezza) {
this.larghezza = larghezza;
}

public int getAltezza() {
return this.altezza;
}

public void setAltezza(int altezza) {
this.altezza = altezza;
}
}

mi stampa la dimensione della cartolina (messa orizzontalmente) e tutto quello che mi serve.

ora come potete vedere io potrei avere più clienti, e avevo pensato ad 2 soluzioni:
1) (quella implementata) un for sui clienti
2) utilizzo della classe book.

al 1 abbiamo il problema che mi appare il dialog ogni volta, e se "bypasso" il dialog mi sfasa la dimensione (suppongo che serva appunto a quello il dialog)

il 2 non sò come funziona.

chi mi può aiutatre in uno dei due casi?

franksisca
17-07-2009, 15:45
risolto...ho invertito un pò l'ordine delle cose cosi:

public void stampa() throws PrinterException {
this.paper.setSize(this.larghezza, this.altezza);
this.paper.setImageableArea(20, 20, this.larghezza, this.altezza);
this.pageFormat.setPaper(this.paper);
this.paginaStampante.setPageFormat(this.pageFormat);
this.paginaStampante.setMessaggio(this.messaggio);
PrinterJob pj = PrinterJob.getPrinterJob();
pj.printDialog();// da commentare
pj.defaultPage(this.pageFormat);
pj.setPrintable(this.paginaStampante);
for (int i = 0; i < this.clienti.size(); ++i) {
this.paginaStampante.setClienti(this.clienti.get(i));

pj.print();
}
}


lascio tutto qui così serve a qualcuno :D