Utilizzando la classe Graphics

Una varietà di fattori ispira le persone a scrivere programmi software. Credo che per molti la motivazione nasca dal desiderio di creare grafica, manipolare immagini o animare. Sia che vogliano creare giochi arcade, simulatori di volo o pacchetti CAD, gli sviluppatori spesso iniziano imparando a disegnare.

La casella degli strumenti grafica all'interno di Abstract Windowing Toolkit (o AWT) consente a un programmatore Java di disegnare semplici forme geometriche, stampare testo e posizionare immagini all'interno dei bordi di un componente, come una cornice, un pannello o una tela.

Questa è la mia prima colonna sul tema della grafica. Si concentrerà sulla Graphicsclasse e sui suoi metodi per disegnare forme geometriche semplici e introdurrà il processo mediante il quale avviene la pittura (e la ridipintura).

Cominciamo dal centro della scena: la Graphicsclasse.

La classe Graphics

È essenziale che i programmatori comprendano la Graphicsclasse prima di tentare di disegnare immagini tramite Java. La Graphicsclasse fornisce il framework per tutte le operazioni grafiche all'interno dell'AWT. Interpreta due ruoli diversi, ma correlati. Innanzitutto, è il contesto grafico. Il contesto grafico è informazioni che influenzeranno le operazioni di disegno. Ciò include i colori di sfondo e primo piano, il carattere e la posizione e le dimensioni del rettangolo di ritaglio (l'area di un componente in cui è possibile disegnare la grafica). Include anche informazioni sulla destinazione finale delle operazioni grafiche stesse (schermo o immagine). Secondo, ilGraphicsclass fornisce metodi per disegnare semplici forme geometriche, testo e immagini nella destinazione grafica. Tutto l'output nella destinazione grafica avviene tramite una chiamata di uno di questi metodi.

Per disegnare, un programma richiede un contesto grafico valido (rappresentato da un'istanza della Graphicsclasse). Poiché la Graphicsclasse è una classe base astratta, non può essere istanziata direttamente. Un'istanza viene generalmente creata da un componente e passata al programma come argomento dei metodi update () e paint () di un componente . Questi due metodi, insieme al metodo repaint () , sono discussi nella sezione successiva.

I metodi

I tre metodi seguenti sono coinvolti nella visualizzazione della grafica. Le versioni predefinite di ciascuno sono fornite dalla classe Component. I metodi update () e paint () dovrebbero essere ridefiniti per eseguire le operazioni grafiche desiderate.

riverniciare()

public void repaint () public void repaint (long tm) public void repaint (int x, int y, int w, int h) public void repaint (long tm, int x, int y, int w, int h)

Il metodo repaint () richiede che un componente venga ridipinto. Il chiamante può richiedere che la riverniciatura avvenga il prima possibile o può specificare un periodo di tempo in millisecondi. Se viene specificato un periodo di tempo, l'operazione di pittura verrà eseguita prima che sia trascorso il periodo di tempo. Il chiamante può anche specificare che solo una parte di un componente deve essere ridipinta. Questa tecnica è utile se l'operazione di disegno richiede molto tempo e solo una parte del display necessita di essere ridipinta. Il codice nel Listato 1 illustra come il metodo repaint () potrebbe essere utilizzato in un programma.

booleano mouseDown (Evento e, int x, int y) {selected_object.move (x, y); riverniciare(); }

Listato 1: gestore di eventi mouse-down

Il codice nel gestore di eventi mouseDown () ricalcola la posizione di un oggetto in un display in base alla posizione del mouse e chiama il metodo repaint () per indicare che il display deve essere ridipinto il prima possibile.

aggiornare()

aggiornamento public void (grafica g)

Il metodo update () viene chiamato in risposta a una richiesta repaint () , o in risposta a una parte del componente che viene scoperta o visualizzata per la prima volta. L'unico argomento del metodo è un'istanza della Graphicsclasse. L' Graphicsistanza è valida solo nel contesto del metodo update () (e di qualsiasi metodo chiamato), ma viene eliminata subito dopo il ritorno del metodo update () . L'implementazione predefinita fornita dalla Componentclasse cancella lo sfondo e chiama il metodo paint () (sotto).

dipingere()

public void paint (grafica g)
Il metodo paint () viene chiamato da un metodo update () ed è responsabile del disegno effettivo della grafica. L'unico argomento del metodo è un'istanza della Graphicsclasse. L'implementazione predefinita fornita dalla classe Componentnon fa nulla.

Come vengono ridipinti i componenti

Per ridurre il tempo necessario per ridipingere il display, l'AWT utilizza due scorciatoie:

  • In primo luogo, l'AWT ridipinge solo quei componenti che devono essere riverniciati, o perché sono stati scoperti o perché hanno chiesto di essere ridipinti.


    
  • In secondo luogo, se un componente è stato coperto ed è scoperto, l'AWT ridipinge solo la parte del componente precedentemente coperta.

L'applet nella Figura 1 consente di osservare questo processo mentre si verifica. Ignora per un momento l'area di testo nella parte superiore dell'applet e osserva solo la parte colorata del display. Utilizzando un'altra finestra, copri momentaneamente e poi scopri una parte dell'applet. Notare che solo la parte dell'applet che era coperta viene ridipinta. Inoltre, vengono ridipinti solo i componenti che sono stati coperti, indipendentemente dalla loro posizione nella gerarchia dei componenti. Utilizzando deliberatamente colori diversi, l'applet rende evidente questo sottile effetto. Il codice sorgente per questa figura è disponibile qui.

Figura 1: ridipingere il browser

Il sistema di coordinate grafiche

I metodi descritti nella sezione seguente accettano, come parametri, valori che specificano come deve essere disegnata una forma. Ad esempio, il metodo drawLine () prevede quattro parametri. I primi due parametri specificano la posizione dell'inizio della riga e gli ultimi due parametri specificano la posizione della fine della riga. I valori esatti da passare al metodo drawLine () sono determinati dal sistema di coordinate in vigore.

Un sistema di coordinate è un metodo per specificare in modo inequivocabile la posizione dei punti nello spazio. Nel caso dell'AWT, questo spazio è una superficie bidimensionale chiamata piano. Ogni posizione in un piano può essere specificata da due numeri interi, chiamati coordinate x e y . I valori delle x ed y coordinate sono calcolate in termini di rispettivi spostamento orizzontale e verticale del punto dall'origine. Nel caso dell'AWT, l'origine è sempre il punto nell'angolo superiore sinistro del piano. Ha i valori delle coordinate 0 (per x ) e 0 (per y). L'illustrazione nella Figura 2 mostra due punti: uno situato all'origine e un altro situato in una posizione sette attraverso e cinque sotto l'origine.

Figura 2: il piano delle coordinate

Le primitive grafiche

Questa sezione introduce metodi per disegnare linee, rettangoli, ovali e archi e poligoni. Poiché questi metodi funzionano solo se invocati su Graphicsun'istanza valida , possono essere utilizzati solo nell'ambito dei metodi update () e paint () di un componente . La maggior parte dei metodi che seguono sono disponibili in coppia. Un metodo (il metodo drawX () ) disegna solo il contorno della forma specificata, e l'altro metodo (il metodo fillX () ) disegna una versione piena della forma specificata.

Linee

void drawLine (int xBegin, int yBegin, int xEnd, int yEnd)

Questo è il più semplice di tutti i metodi grafici. Disegna una linea retta, larga un singolo pixel, tra i punti iniziale e finale specificati. La linea risultante verrà ritagliata per adattarsi ai confini della regione di ritaglio corrente. La linea verrà tracciata nel colore di primo piano corrente.

L'applet nella Figura 3 mostra il metodo drawLine () in azione. Il codice sorgente è disponibile qui. Questa applet e le applet nelle Figure 4, 6 e 7 richiedono i servizi di due classi di supporto: la classe NewCanvas e l'interfaccia Figure. La classe NewCanvas estende la classe Canvas e fornisce una superficie di disegno specializzata per le figure. Il codice sorgente per la classe NewCanvas è disponibile qui. L'interfaccia Figure definisce i metodi che una figura deve fornire per essere utilizzata con NewCanvas. Il codice sorgente per l'interfaccia Figure è disponibile qui.

Figura 3: dimostrazione del disegno al tratto

rettangoli
void drawRect (int x, int y, int w, int h) void fillRect (int x, int y, int w, int h) void drawRoundRect (int x, int y, int w, int h, int arcWidth, int arcHeight ) void fillRoundRect (int x, int y, int w, int h, int arcWidth, int arcHeight) void draw3DRect (int x, int y, int w, int h, booleano elevato) void fill3DRect (int x, int y, int w, int h, booleano elevato)

Ciascuno di questi metodi grafici richiede, come parametri, le coordinate xey da cui iniziare il rettangolo e la larghezza e l'altezza del rettangolo. Sia la larghezza che l'altezza devono essere numeri interi positivi. Il rettangolo risultante verrà ritagliato per adattarsi ai limiti della regione di ritaglio corrente. Il rettangolo verrà disegnato nel colore di primo piano corrente. I rettangoli sono disponibili in tre diversi stili: semplici, con angoli arrotondati e con un leggero (ma spesso difficile da vedere) effetto tridimensionale.

I metodi grafici con rettangolo arrotondato richiedono due parametri aggiuntivi, una larghezza e un'altezza dell'arco, che controllano entrambi l'arrotondamento degli angoli. I metodi del rettangolo tridimensionale richiedono un parametro aggiuntivo che indica se il rettangolo deve essere infossato o rialzato.

L'applet nella Figura 4 mostra questi metodi in azione. Il codice sorgente è disponibile qui.

Figura 4: dimostrazione del disegno del rettangolo

ovali e archi

void drawOval (int x, int y, int w, int h) void fillOval (int x, int y, int w, int h) void drawArc (int x, int y, int w, int h, int startAngle, int arcAngle ) void fillArc (int x, int y, int w, int h, int startAngle, int arcAngle)

Ciascuno di questi metodi grafici richiede, come parametri, le coordinate xey del centro dell'ovale o dell'arco e la larghezza e l'altezza dell'ovale o dell'arco. Sia la larghezza che l'altezza devono essere numeri interi positivi. La forma risultante verrà ritagliata per adattarsi ai confini della regione di ritaglio corrente. La forma verrà disegnata nel colore di primo piano corrente.

The arc graphics methods require two additional parameters, a start angle and an arc angle, to specify the beginning of the arc and the size of the arc in degrees (not radians). Figure 5 illustrates how angles are specified.

Figure 5: Angle specification

The applet in Figure 6 demonstrates these methods in action. The source code is available here.

Figure 6: Oval and arc drawing demonstration

polygons

void drawPolygon(int xPoints[], int yPoints[], int nPoints) void drawPolygon(Polygon p) void fillPolygon(int xPoints[], int yPoints[], int nPoints) void fillPolygon(Polygon p)

Polygons are shapes formed from a sequence of line segments. Each of the polygon graphics methods require, as parameters, the coordinates of the endpoints of the line segments that make up the polygon. These endpoints can be specified in either one of two ways: as two parallel arrays of integers, one representing the successive x coordinates and the other representing the successive y coordinates; or with an instance of the Polygon class. The Polygon class provides the method addPoint(), which allows a polygon definition to be assembled point by point. The resulting shape will be clipped to fit within the boundaries of the current clipping region.

The applet in Figure 7 demonstrates these methods in action. The source code is available here.

Figura 7: dimostrazione del disegno del poligono

Conclusione

Che tu ci creda o no, queste poche semplici primitive grafiche, combinate con tutto ciò che abbiamo trattato negli ultimi mesi (l'AWT, la gestione degli eventi, gli osservatori, ecc.) Sono tutto ciò di cui hai bisogno per scrivere un mucchio di applicazioni utili, che vanno da giochi a sistemi CAD. Il mese prossimo metterò insieme tutti questi pezzi e vi mostrerò cosa intendo.

Rimanete sintonizzati.

Todd Sundsted scrive programmi da quando i computer sono diventati disponibili nei modelli desktop. Sebbene inizialmente interessato alla creazione di applicazioni a oggetti distribuiti in C ++, Todd è passato al linguaggio di programmazione Java quando Java è diventato la scelta più ovvia per quel genere di cose. Oltre a scrivere, Todd fornisce servizi di consulenza Internet e Web ad aziende negli Stati Uniti sudorientali. : END_BIO

Ulteriori informazioni su questo argomento

  • L' GraphicsAPI della classe Java

    //java.sun.com/products/JDK/CurrentRelease/api/java.awt.Graphics.html

  • Osservatore e osservabile //www.sun.com/javaworld/jw-10-1996/jw-10-howto.html
  • L'interfaccia utente efficace //www.sun.com/javaworld/jw-09-1996/jw-09-userint.html
  • Java e gestione degli eventi //www.sun.com/javaworld/jw-08-1996/jw-08-event.html
  • Introduzione all'AWT //www.sun.com/javaworld/jw-07-1996/jw-07-awt.html

Questa storia, "Using the Graphics class" è stata originariamente pubblicata da JavaWorld.