2014-10-23 2 views
7

Non sono sicuro di aver capito g.drawString.Stampa su modulo fisico: è necessario conoscere le basi

Ho un programma che scrive su un modulo prestampato. Gli utenti affermano che la stampa è irregolare ... cioè, il testo sul modulo è più alto/più basso rispetto alla stampa precedente. Personalmente, penso che stiano caricando male il modulo, ma dal momento che mi pagano per scrivere codice, sto misurando il modulo e convertendo le dimensioni in pixel e riscrivendo la parte che si occupa della stampa.

Per stampare correttamente il modulo, c.getCostAmount() deve essere stampato un pixel SOPRA c.getAppraisersAmount() affinché appaia una riga sotto di esso. Tuttavia, ogni linea successiva è di 4 mm (o circa 15 pixel) al di sotto di quella.

Il mio problema è che non capisco le distanze verticali e perché la 3a riga deve essere posizionata un pixel sopra la riga precedente perché si trovi al di sotto.

Chiunque ha una spiegazione rapida o semplice di un tutorial/spiegazione?

Grazie mille!

Il codice (h/t Alex, Java: Printing program output to a physical printer):

public int print(Graphics g, PageFormat pf, int page, Check c){ 
    final double MILLIMETER_IN_PIXELS = 3.779527559; 
    DecimalFormat df = new DecimalFormat("$#.00"); 

    if (page > 0) { 
     return NO_SUCH_PAGE; 
    } 

    Graphics2D g2d = (Graphics2D) g; 
    int x = (int) pf.getImageableX(); 
    int y = (int) pf.getImageableY(); 
    g2d.translate(x, y + .5); 

    Font font = new Font("Courier New", Font.PLAIN, 10); 
    g2d.setFont(font); 
    FontMetrics metrics = g.getFontMetrics(font); 
    g.drawString("CHECK #" + c.getCheckNumber(), ((int) MILLIMETER_IN_PIXELS* 55),((int) MILLIMETER_IN_PIXELS*15)); 

    int strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getAppraisersAmount())); 
    g.drawString(df.format(c.getAppraisersAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) MILLIMETER_IN_PIXELS*23)); 

    Date d = c.getJavaDate(); 
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 
    g.drawString(sdf.format(d), ((int) MILLIMETER_IN_PIXELS*90), ((int) MILLIMETER_IN_PIXELS*24)); 

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getCostAmount())); 
    g.drawString(df.format(c.getCostAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*22))); 

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getRefundsAmount())); 
    g.drawString(df.format(c.getRefundsAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*26)));   

    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(c.getOfficersAmount())); 
    g.drawString(df.format(c.getOfficersAmount()), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*30))); 

    Double totalLeft = c.getAppraisersAmount() + c.getCostAmount() + c.getRefundsAmount() + c.getOfficersAmount(); 
    strWidth = SwingUtilities.computeStringWidth(metrics, df.format(totalLeft)); 
    g.drawString(df.format(totalLeft), ((int) ((MILLIMETER_IN_PIXELS*62)-strWidth)), ((int) (MILLIMETER_IN_PIXELS*44))); 

    return PAGE_EXISTS; 
} 
+3

Personalmente, non lo so, ma mi interessa sapere quale sia la risposta! Star da me e applausi a te! – DreadHeadedDeveloper

risposta

0

Non sono sicuro di come hai determinato il valore di MILLIMETER_IN_PIXELS, mi sembra del tutto sospetto.

Tuttavia, l'errore che v'è confusione è semplicemente un caso di sostegni mancanti:

si utilizzano i termini: ((int) MILLIMETER_IN_PIXELS*23), ((int) MILLIMETER_IN_PIXELS*24) e ((int) (MILLIMETER_IN_PIXELS*22)).

noti che i primi due termini hanno le parentesi intorno al prodotto MILLIMETER_IN_PIXELS*… che significa che lanci MILLIMETER_IN_PIXELS di int prima, ottenendo il valore 3, e poi moltiplicano, invece di eseguire una moltiplicazione double primo e colata a int poi.

Pertanto gli errori di arrotondamento sono diversi. I valori risultanti sono 69, 72, 83.

Nota che l'errore di parentesi graffe mancante viene visualizzato anche in un altro punto, anche le posizioni orizzontali sono interessate.


Come un addendum, ecco come si ottiene la vera DPI:

Point2D p = g2d.getDeviceConfiguration().getDefaultTransform() 
    .transform(new Point2D.Float(72,72),null); 
// normally, both are the same 
int horizontalDPI=(int)p.getX(), verticalDPI=(int)p.getY(); 

Spiegazione: la trasformazione di default è specificato come una trasformazione che trasformerà pixel 72 user-space a un pollice, così quando applicando la trasformazione a 72, il risultato sarà il numero di pixel del dispositivo corrispondenti a un pollice.

+0

Quindi è CPEMDAS? :) –

+0

Questo era il problema, quindi. Grazie, sia per risolverlo sia per rafforzare la mia convinzione nella mia comprensione di Java. –

+1

Le parentesi hanno una priorità più alta di cast, ma il cast viene prima della moltiplicazione (l'esponente non si applica in quanto non esiste un operatore di questo tipo in Java). A proposito, in caso di dubbio, puoi mettere tra parentesi qualsiasi cosa e quindi premere CTRL + 1 in Eclipse e scegliere "Rimuovi parentesi extra" dal menu popup che rimuoverà tutte le parentesi obsolete ma manterrà tutte quelle necessarie. – Holger

0

Im non che bravo a farlo io sia, ma in un libro che ho letto ci fosse davvero una buona explination su tekst e come si comporta quando dipinto. Ho cercato un'esplosione di sorriso e ne ho trovato uno da Oracle. Eccolo: http://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html Non è buono ma è qualcosa. Il problema con tekst è che devi prendere in considerazione il declino ascendente e la linea di base per dipingerlo correttamente. Mi dispiace di non poter essere più di aiuto, spero che la pagina di Oracles sia abbastanza utile.

+0

Ho letto quel link in precedenza ... mi ha aiutato ad arrivare al punto in cui mi trovo ora, in realtà. Se ricordi il nome del libro, fammi sapere. Mia moglie non sta facendo nulla, può correre verso la libreria. :) –

+1

Beh, il libro era in realtà un'app digitale per Android e mi è stato chiamato un 'introduzione alla programmazione java' ed è stato creato da thu gian viet. Era il mio primo libro e credo che la parte sui caratteri sia da qualche parte vicino alla fine. Non so se copre molto di più però. tra l'app è gratis. – Roan

+0

A proposito c'è una versione online del libro qui: http://math.hws.edu/javanotes/ – Roan