Sei sulla pagina 1di 8

Creazione di un frame

In java una finestra top-level (a livello superiore), ovvero una finestra che non è contenuta in
un’altra finestra, prende il nome di frame. La libreria AWT (Abstract Window Toolkit) ha una classe
di nome Frame per questo tipo di finestre. La versione swing di questa classe è chiamata JFrame
ed estende la classe Frame. La classe JFrame è uno dei pochi componenti swing che non viene
disegnato in un riquadro già definito. Pertanto, le decorazioni (pulsanti, barre, icone e cosi via)
sono disegnate dal sistema di finestre dell’utente, non da swing.
Esempio creazione semplice frame:
import javax.swing.*;
public class MyFrameTest {
public static void main(String[] args ) {
MyFrame frame = new MyFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class MyFrame extends JFrame {
public MyFrame() {
setSize(300, 200);
}
}
}

Le classi del package swing si trovano nel pacchetto javax.swing. L’esempio definisce una
sottoclasse MyFrame i cui costruttori impostano una dimensione del frame di 300 x 200 pixel.
 La costruzione di un oggetto MyFrame ha inizio nel metodo main della classe
MyFrameTest

 Per definire ciò che accade quando l’utente chiude il frame si utilizza la seguente istruzione
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

l’impostazione predefinita prevede che un frame venga nascosto quando l’utente lo chiude
senza che il programma venga terminato.

 La vita dei frame è inizialmente invisibile per permettere ai programmatori di aggiungere


componenti prima di mostrarlo. Per mostrare un frame si usa il seguente metodo:

setVisible(true).
Posizionamento di un frame
La classe JFrame ha alcuni metodi che permettono di modificare l’aspetto dei frame. Di seguito
sono elencati i metodi più importanti:
 dispose chiude la finestra e rilascia le risorse del sistema utilizzate per la sua creazione,
 setIconImage riceve un oggetto Image da utilizzare come icona della finestra ridotta a
icona,
 setTitle modifica il testo nella barra del titolo,
 setResizable riceve un boolean per stabilire se un frame può essere ridimensionato
dall’utente.
Le API stabiliscono che la classe Component, genitore di tutti gli oggetti GUI e la classe
Window, superclasse della classe Frame, definiscono i metodi che permettono di
ridimensionare e ridisegnare i frame:
 setLocation(x, y) permette di riposizionare un componente. In particolare stabilisce che
l’angolo superiore sinistro sia posizionato a x pixel in orizzontale e y pixel in verticale
rispetto all’angolo superiore sinistro dello schermo

 setBounds(x, y, base, altezza) permette di ridimensionare e riposizionare un componente,


in particolare un JFrame, con un solo passaggio.

Centrare un frame nello schermo


In un’applicazione professionale però si deve verificare la risoluzione dello schermo dell’utente e
scrivere codice che possa ridimensionare i frame tenendo conto di questa indicazione. Per
individuare la dimensione dello schermo si devono osservare i seguenti passi:
 Si chiama il metodo statico getDefaultToolkit della classe Toolkit per ricavare l’oggetto
Toolkit. La classe Toolkit è un terreno molto fertile per trovare molti metodi che si
interfacciano con il sistema a finestre nativo;

 Poi si chiama il metodo getScreenSize, che restituisce la dimensione dello schermo come
oggetto Dimension;

 Dopo aver impostato la dimensione del proprio Frame con il metodo setSize, è possibile
centrare il frame nello schermo utente. Di seguito è riportato il codice che si deve seguire:
Toolkit kit = Toolkit.getDefaultToolkit():
Dimension dim = kit.getScreenSize();
int screenWidth = dim.width;
int screenHeight = dim.height;
int x = screenWidth / 2 – getWidth() / 2;
int y = screenHeight / 2 – getHeight() /2;
setLocation(x, y);
Visualizzazione di informazioni in un pannello
Si potrebbe disegnare la stringa di un messaggio direttamente nel frame, ma questa non è
considerata una buona pratica di programmazione. In Java i frame sono in genere progettati per
essere dei contenitori di altri componenti dell’interfaccia grafica (barre, menu). Di solito si disegna
un altro componente, chiamato pannello, che viene aggiunto al frame. Quando si progetta un
frame, si aggiungono i componenti nel pannello dei contenuti (content pane):
Container contentPane = frame.getContentPane();
Component c = . . . ;
contentPane.add(c);

Ma a partire da JDK 5.0 è possibile utilizzare semplicemente la seguente chiamata:


frame.add(c);

I pannelli sono implementati nella classe JPanel e presentano due proprietà molto utili:
 Hanno una superficie nella quale si può disegnare

 Sono essi stessi dei contenitori


In particolare, per ridisegnare un pannello si deve:
 Definire una classe che estende JPanel

 Effettuare l’override del metodo paintComponent


Il metodo paintComponent è in JComponent, la superclasse di tutti i componenti Swing che non
sono finestre. Il metodo ha un parametro di tipo Graphics. Un oggetto Graphics contiene le
impostazioni per disegnare immagini e testo, per esempio il font impostato o il colore corrente: in
Java tutti i disegni devono passare attraverso un oggetto Graphics.
public void paintComponent(Graphics g) {
super.paintComponent(g);
//codice per disegnare ( es. g.drawString(test, x y) )
}

Si deve richiamare super.paintComponent() per essere sicuri che la superclasse faccia la sua parte
di lavoro poiché JPanel implementa già una propria logica di disegno del pannello.
Nota bene:
Non si deve mai chiamare direttamente il metodo paintComponent. Questo metodo è chiamato
automaticamente ogni volta che una parte dell’applicazione deve essere ridisegnata, e non si deve
interferire con questo processo automatica.
Se si deve forzare il ridisegno del pannello, al posto di paintComponent si chiama il metodo
repaint, il quale fa sì che venga chiamato il metodo paintComponent di tutti i componenti al suo
interno, con un oggetto Graphics opportunamente configurato.
Lavorare con forme 2D
La libreria che implementa un interessante set di operazioni grafiche è chiamata Java2D. Per
disegnare le forme nella libreria Java2D è necessario ottenere un oggetto della classe Graphics2D.
Questa è una sottoclasse della classe Graphics. I metodi, per esempio paintComponenet, ricevono
automaticamente un oggetto della classe Graphics2D. Per utilizzarlo è sufficiente un cast, come
segue:
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
}

La libreria organizza le forme geometriche in una modalità orientata agli oggetti; in particolare, si
possono utilizzare le classi Point2D, Line2D, Rectangle2D, Ellipse2D. Queste classi implementano
tutte l’interfaccia Shape.
Per disegnare una forma si deve chiamare il metodo draw della classe Graphics2D, come
nell’esempio seguente:
Rectangle2D rect = . . . ;
g2.draw(rect);

Per esprimere le coordinate, le forme 2D utilizzano numeri in virgola mobile. I progettisti della
libreria Java2D hanno messo a disposizione due versioni di ogni classe di forme: una con
coordinate float, l’altra con coordinate double. Ad esempio la classe Rectangle2D è una classe
astratta con due sottoclassi concrete che sono anche classi interne statiche:
Rectangle2D.Float e Rectangle2D.Double
Si possono utilizzare semplicemente le variabili Rectangle2D per gestire i riferimenti dei rettangoli:
Rectangle2D floatRect = new Rectangle2D.Float (10.0F, 25.0F, 22.0F, 20.0F);
Rectangle2D doubleRect = new Rectangle2D.Double (10.0, 25.0, 22.0, 20.0);

I parametri di costruzione indicano rispettivamente l’angolo superiore sinistro, la larghezza e


l’altezza del rettangolo.
Utilizzare i colori
Il metodo setPaint della classe Graphics2D permette di selezionare un colore che verrà utilizzato
per tutte le successive operazioni di disegno sul contesto grafico. Per disegnare con colori diversi,
si seleziona un colore e si disegna, poi se ne seleziona un altro e si disegna di nuovo. I colori
vengono definiti con la classe java.awt.Color che offre costanti predefinite per i 13 colori
standard:
BLACK BLUE CYAN DARK_GRAY GRAY
GREEN LIGHT_GRAY MAGENTA ORANGE PINK
RED WHITE YELLOW - -

Esempio:
g2.setPaint(Color.RED);
g2.drawString(“Warning!”, 100, 100);

E’ possibile specificare un colore personale creando un oggetto Color in base alle componenti di
colore rosso, verse e blu. Per indicare si utilizza una scala da 0 a 255 (cioè, un byte) e si chiama il
costruttore Color(int red, int green, int blue)
Esempio:
g2.setPaint(new Color(0,128,128)); //un verde-azzurro pallido

Per impostare il colore di sfondo si utilizza il metodo setBackground della classe Component,
superclasse di JPanel.
Esempio:
MyPanel p = new MyPanel(); p.setBackground(Color.BLUE);

“Nota: I metodi brighter() e darker() della classe Color producono rispettivamente versioni più
chiare o più scure del colore corrente”
Java mette a disposizioni nomi predefiniti per molti altri colori nella classe SystemColor. Le
costanti di questa classe incapsulano i colori utilizzati per diversi elementi del sistema su cui opera
l’utente:
p.setBackgroundd(SystemColor.window)

Questa istruzione, per esempio, imposta il colore di sfondo del pannello uguale a quello utilizzato
da tutte le finestre del desktop dell’utente.
Riempire le forme
E’ possibile riempire la parte interna delle forme chiuse, per esempio rettangolo o ellissi, con un
colore, o più in generale con l’impostazione specificata dall’oggetto Paint utilizzato. E’ sufficiente
chiamare il metodo fill al posto di draw:
Rectangle2D rect = . . . ;
g2.setPaint(Color.RED);
g2.fill(rect);

Utilizzare font speciali per il testo


Per individuare i font disponibili su un determinato computer si chiama il metodo
getAvailableFontFamilyNames della classe GraphicsEnvironment. Il metodo restituisce un array di
stringhe che contiene i nomi dei font disponibili. Per ottenere un’istanza della classe
GraphicsEnvironment che descriva l’ambiente grafico del sistema utente si utilizza il metodo
statico getLocalGraphicsEnvironment. La seguente istruzione memorizza nell’array fonts tutti i
font installati nel sistema:
String[] fonts =
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

Sfortunatamente non c’è modo di sapere se un utente dispone di un font con un particolare
aspetto. Per stabilire una linea di base comune, la libreria AWT definisce cinque nomi di font logici:
SansSerif Serif Monospaced Dialog DialogInput
Questi nomi sono sempre mappati con font che esistono nei computer client, Per esempio, in un
sistema Windows SansSerif è mappato in Arial.
Per disegnare i caratteri di un font si deve prima creare un oggetto della classe Font.
Esempio:
Font sans = new Font(“SansSerif”, Font.BOLD, 14)

 Nel primo argomento viene specificato il nome del font


 Nel secondo argomento si specifica lo stile scegliendo tra uno dei seguenti valori:

Font.PLAIN Font.BOLD
Font.ITALIC Font.BOLD + Font.ITALIC

 Il terzo argomento definisce la dimensione in punti. I punti sono utilizzati di solito in tipografia
per stabilire la dimensione di un font. In un pollice ci sono 72 punti.
Disegnare una stringa e centrarla nel contenitore
 Di seguito è indicato il codice che visualizza la stringa “Hello World!” con il font standard
SansSerif presente nel sistema, utilizzando il grassetto e una dimensione di 14 punti:
Font sansbold14 = new Font(“SansSerif”, Font.BOLD, 14);
g2.setFont(sansbold14);
String message = “Hello World!”;
g2.drawString(message, 75, 100);

 A questo punto è possibile centrare la stringa nel suo pannello invece di disegnarla in una
posizione arbitraria. E’ necessario conoscere la larghezza e l’altezza della stringa in pixel.
Queste dimensioni dipendono da tre fattori:

o Il font utilizzato; nell’esempio sans serif, bold, 14

o La lunghezza della stringa; nell’esempio, “Hello World!”

o Il dispositivo nel quale si disegna il font; nell’esempio, lo schermo dell’utente

 Per ottenere un oggetto che rappresenta le caratteristiche del font sullo schermo, si chiama il
metodo getFontRenderContext della classe Graphics2D che restituisce un oggetto della classe
FontRenderContext. Si passa poi questo oggetto al metodo getStringBounds della classe Font:
FontRenderContext context = g2.getFontRenderContext();
Rectangle2D bounds = sansbold14.getStringBounds(message, context);

 La larghezza del rettangolo restituita dal metodo getStringBounds definisce l’estensione


orizzontale della stringa, mentre la sua altezza è la somma di ascesa, discesa e interlinea
(termini tipici della tipografia)
Il codice che segue utilizza queste informazioni per centrare una stringa nel pannello che la
circonda:
// (x, y) = angolo superiore sinistro del testo
double x = (getWidth() – bounds.getWidth()) / 2;
double y = (getHeight () – bounds.getHeight ()) / 2;
// aggiunge l’ascesa a y per raggiungere la linea di base
double ascent = -bounds.getY(); // la coordinata y del rettangolo è negativa
double baseY = y + ascent;
g2.drawString(message, (int) x, (int) baseY);
Ottenere di più dalle immagini
Le immagini memorizzate in file locali o su Internet possono essere lette in un’applicazione Java e
visualizzate da oggetti Graphics.
 Se l’immagine è memorizzata in un file locale si possono utilizzare le seguenti righe di codice:
String filename = “. . .”;
Image image = Image.IO.read(new File(filename));

 In alternative è possibile indicare un URL:


String urlname = “. . .”;
Image image = Image.IO.read(new URL(urlname));

Se l’immagine non è disponibile il metodo read genera un’eccezione IOException.


A questo punto la variabile image contiene un riferimento a un oggetto che incapsula i dati
dell’immagine.

 E’ possibile visualizzare l’immagine con il metodo drawImage della classe Graphics:


g.drawImage(image, x, y, null);

Potrebbero piacerti anche