PDA

View Full Version : [Java] Problemi con il fillRect


:.Blizzard.:
25-07-2009, 16:03
Allora ragazzi, salve a tutti. Ho un problema da cui non riesco a venirne fuori (è più di un'ora che ci stò ragionando :stordita: ).

Stò facendo un programma in Java che gestisce il database di una fittizia casa edistrice. Ho deciso di fare in modo che l'utente possa visualizzare l'istogramma delle vendite dei numeri di una collana. Così ho scritto un codice per disegnare questo istogramma:

public void paintComponent(Graphics g) {
super.paintComponent(g);
int max = findMax(this.venduti);


g.setColor(new java.awt.Color(160, 175, 219));
for (int i = 0; i < dim; i++) {
g.fillRect(30 + i * 50, 25, 30, Math.round((250 * (Integer) venduti[i][1]) / max));
}


Nota: l'array bidimensionale che vedete contiene il numero i-esimo della collana e al suo fianco il numero di prodotti venduti di tale numero.

Il problema è che il fillRect mi considera il conteggio dei pixel a partire da in alto a sx anzichè dal basso a sx. Ecco quindi cosa ne viene fuori:

http://img269.imageshack.us/img269/3069/capturedqi.jpg

Ovvero l'istogramma esce fuori ribaltato.

Considerate che il JPanel ha altezza 300 pixel.
Ho deciso di usare sia un margine alto che un margine basso ciascuno di 25 pixel. Ecco perchè nella proporzione ho assegnato al libro di collana con maggior numero di vendite un rettangolo di altezza 250.


Il metodo fillRect è il seguente:

fillRect(int x, int y, int width, int height)

Ovvero disegna un rettangolo il cui angolo in alto a sinistra è nelle coordinate x,y; il rettangolo è largo WIDTH ed è alto HEIGHT (quindi niente altezze negative).

Potete darmi una mano?

:.Blizzard.:
25-07-2009, 16:12
come non detto, con carta e penna e disegnino ci sono arrivato ... era molto banale :

g.fillRect(30 + i * 50, altezza - 25 - Math.round((250 * (Integer) venduti[i][1]) / max), 30, Math.round((250 * (Integer) venduti[i][1]) / max));


:D

banryu79
27-07-2009, 08:13
Potevi anche risolvere così:

1) eseguo sul Graphics la traslazione dell'origine (che come avrai capito è mappata nel punto in alto a sinistra del componente su cui si disegna) nel punto in basso a sinistra (sfruttando la getHeight del componente);
2) eseguo sul Graphics una operazione di scala di valore 1 per le X e valore -1 per le Y

A questo punto avresti ottenuto il rendering corretto anche specificando l'operazione di disegno fillRect con i valori postati nella tua prima versione.

Se devi poi "resettare" lo stato del Graphics, basta salvarsi la sua AffineTransform prima di eseguire le operazioni ai punti 1) e 2); per poi ripristinarla tramite il metodo setTransform del Graphics.

Se vuoi approfondire, questo (http://java.sun.com/docs/books/tutorial/2d/overview/index.html) potrebbe essere un buon punto di partenza.