In questo secondo appuntamento inizieremo il nostro giro sui vari framework che compongono le IFC iniziando a parlare di quell'insieme di classi che si occupano della gestione dello schermo
La gestione dello schermo: Le viste
I concetti di vista e rettangolo di ingombro sono essenziali per capire le modalita' con le quali le IFC permettono di gestire lo schermo. Per vista si intende una porzione di schermo la cui posizione e dimensione viene definita attraverso il rettangolo di ingombro ed ogni operazione di disegno agisce solamente entro questi limiti, cio' significa che il rettangolo di ingombro assume una funzione di clipping che impedisce di fatto il disegno al di fuori dei propri confini, inoltre la vista ricevera' gli eventi solo se sono stati provocati all'interno di questo rettangolo.
Le classi atte a rappresentare la vista ed il rettangolo di ingombro sono, rispettivamente, la View e la Rect, dove la View e' la classe da cui derivano tutti i componenti dell'interfaccia utente delle IFC. Capire quindi il meccanismo che sta dietro al disegno delle viste (e quindi dei compoennti) permette di avere una padronanza completa sulle tecniche da utilizzare per creare i propri controlli.
Il metodo draw
Il disegno di una vista e' affidato al metodo draw che a sua volta chiama il metodo drawView che si occupa effettivamente di disegnare i contenuti della vista. In ogni caso non si deve mai chiamare direttamente il metodo drawView, ma bisognera' sempre utilizzare il metodo draw, visto che quest'ultimo effettua delle operazioni di preparazione che serviranno successivamente.
Alcune particolari viste possono avere piu' metodi che iniziano con drawView (ad esempio drawViewInterior,drawViewKnob) che si occupano di disegnare particolari zone della vista stessa e che sono chiamati direttamente all'interno della drawView.
Ad esempio la classe Button che si occupa di implementare il classico pulsante, chiama, all'interno del proprio drawView i metodi :
- drawViewBackground (che si occupa di disegnare lo sfondo del pulsante),
- drawViewInterior (che si occupa di disegnare il contenuto del pulsante),
- drawViewTitleInRect (che si occupa di disegnare il testo all'interno del pulsante).
Supponiamo adesso di voler implementare un pulsante che fornisca un aspetto tridimensionale al testo inserito, bene per farlo dovremo solamente cambiare il metodo drawViewTitleInRect, il seguente codice implementa una nuova classe, chiamate ASC3DButton, derivata dalla Button che da un'aspetto tridimensionale al testo del pulsante:
/**
Programma di esempio per gli articoli sulle IFC per MokaByte
*/
import
netscape.application.*;
import
netscape.util.*;
// Componente
ASCButton che implementa un pulsante con il testo tridimensionale
class ASCButton
extends Button {
// Costruttore
public ASCButton(int x, int y, int width, int height)
{
super(x,y,width,height);
}
// Metodo chiamato per disegnare il testo all'interno del pulsante
public void drawViewTitleInRect(Graphics g,String title,Font titleFont,Rect
textBounds,int justification)
{
// Mantiene traccia del colore di default del testo
Color backTitleColor = titleColor();
// Inizio operazioni per dare l'aspetto tridimensionale
setTitleColor(Color.gray);
// Setta il colore grigio
Rect tempRect = new Rect(textBounds); // Crea un nuovo Rect
con le impostazioni di quello necessario per il testo
tempRect.moveBy(-1,-1);
// Sposta l'origine di un pixel verso sopra e verso sinistra
super.drawViewTitleInRect(g,title,titleFont,tempRect ,justification);
setTitleColor(Color.white);
// Setta il colore grigio
tempRect.moveBy(2,2);
// Sposta l'origine di un pixel verso sotto e verso destra
super.drawViewTitleInRect(g,title,titleFont,tempRect ,justification);
// Fine operazioni per dare l'aspetto tridimensionale
// Ripristina il colore e disegna il testo nella sua posizione originale
setTitleColor(backTitleColor);
super.drawViewTitleInRect(g,title,titleFont,textBounds ,justification);
}
}
/*
*
*
IFCDemo - Applicazione di esempio
*
by Antonino S. CUTRI'
*
*/
public
class IFCDemo extends Application implements Target, WindowOwner
{
public void init() {
super.init();
// Imposta il colore di sfondo
mainRootView().setColor(Color.white);
// Crea il pulsante e lo visualizza
ASCButton btn = new ASCButton(10,10,80,40);
btn.setTitle("Prova");
mainRootView().addSubview(btn);
}
public void performCommand(String command, Object data) {
}
public boolean windowWillShow(Window aWindow) {
return true;
}
public void windowDidShow(Window aWindow) {
}
public boolean windowWillHide(Window aWindow) {
return true;
}
public void windowDidHide(Window aWindow) {
stopRunning();
}
public void windowDidBecomeMain(Window aWindow) {
}
public void windowDidResignMain(Window aWindow) {
}
public void windowWillSizeBy(Window aWindow, Size deltaSize) {
}
/**
*/
public static void main(String args[]) {
IFCDemo app;
app = new IFCDemo();
ExternalWindow mainWindow = new ExternalWindow();
mainWindow.setOwner(app);
app.setMainRootView(mainWindow.rootView());
// Richiede un'area di 128 x 128 pixel
Size size = mainWindow.windowSizeForContentSize(128, 128);
mainWindow.sizeTo(size.width, size.height);
mainWindow.show();
app.run();
System.exit(0);
}
}
Come possiamo notare l'utilizzo di metodi del tipo drawViewXXX ci permette, in maniare abbastanza semplice, di cambiare l'aspetto estetico di qualsiasi componente con poche righe di codice. Questo grazie al fatto che il disegno di una vista e' affidato ad entita' discrete che ci danno l'opportunita' di concentrarci solamente sulla parte da cambiare senza doverci preoccupare di gestire tutti gli aspetti legati al ridisegno.
Se le operazioni di ridisegno di una vista sono troppo onerose in termini di tempi di esecuzione puo' capitare l'antiestetico effetto dello sfarfallamento, fortunatamente anche in questo caso le IFC ci vengono in aiuto. Infatti e' possibile attivare la tecnica del doppio buffer per velocizzare le operazioni di disegno, per farlo bastera' richiamare il metodo setBuffered della vista passandogli true come parametro:
XXXX.setBuffered(true);
Ovviamente l'utilizzo della tecnica del doppio buffer se da un lato elimina l'effetto dello sfarfallamento dall'altro incrementa la quantita' di memoria necessaria alla vista perche' deve utilizzare un buffer aggiuntivo. Inoltre se si utilizza pesantemente la capacita' di buffering si avra' alla fine un decadimento di prestazioni nel ridisegno di tutte le viste, soprattutto su macchine lente, perche' le IFC dovranno effettuare operazioni di copia dal buffer temporaneo allo schermo.
I componenti
I componenti possono essere considerati come i mattoni che permettono di realizzare un'interfaccia utente, fanno parte di questa categoria i pulsanti, le righe di inserimento di testo, le finestre, ecc...
Tutti i componenti derivano dalla classe View, e per utilizzarli basta aggiungere il package netscape.application al proprio sorgente.
I componenti standard forniti dalle IFC sono:
- Button - Pulsante;
- CheckBox - Casella di scelta
- ColorChooser - Finestra che permette di scegliere un colore agendo sulle componenti Rosso Verde e Blu
- ColorWell - Permette di cambiare il colore agli elementi dell'interfaccia utente
- ContainerView - Contenitore di altri componenti
- ExternalWindow - Finestra che conserva il look nativo della piattaforma in cui si sta eseguendo il codice
- FileChooser - Finestra che permette di scegliere un file
- FontChooser - Finestra che permette di scegliere ed impostare le caratteristiche di un font
- InternalWindow - Finestra standard delle IFC, conserva lo stesso aspetto su tutte le piattaforme perche' e' costruita completamente da zero, per questo motivo puo' esistere solo all'interno di una ExternalWindow o di un'applet. Usando una terminologia familiare agli sviluppatori Windows puo' essere considerata come la finestra Child di un'applicazione MDI.
- ListView - Lista di scelta
- Popup - Menu a comparsa
- RadioButton - Pulsante radio
- Slider - Interruttore incrementale che permette di variare un valore in un determinato range
- TextField - Campo di immisione testo, puo' essere usato anche per creare una Label
- TextView - Campo per memorizzare piu' linee di testo. E' possibile anche la gestione di formattazione differente dei paragrafi o di variazione del font utilizzato. Ha anche la possibilita' di importare, ed interpretare, i tag di un file HTML conforme alla versione 1.0 dello standard.
Ecco come appare una InternalWindow con alcuni controlli:
Conclusione
Bene, abbiamo terminato la prima parte dedicata ai componenti dell'interfaccia utente, prossima volta vedremo da vicino come creare ed utilizzare le finestre, aggiungere i controlli ed introdurremo la gestione degli eventi.
Ovviamente resto a disposizione per qualunque chiarimento e/o suggerimento riguardante questa serie di articoli.
