Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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.
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
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);
I pannelli sono implementati nella classe JPanel e presentano due proprietà molto utili:
Hanno una superficie nella quale si può disegnare
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);
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);
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)
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:
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);