ereditano direttamente da Component.
|
|
|
- Taddeo Renzi
- 9 anni fa
- Просмотров:
Транскрипт
1 Le interfacce utente grafiche (Graphical User Interface) Il primo package Java che gestisce gli elementi di una GUI 1 è awt. Gli elementi di una GUI si distinguono in oggetti di due tipi: oggetti contenitori oggetti componenti Java usa un sistema generico per gestire la grafica, definendo elementi grafici comuni (oggetti componenti che possono essere contenitori) in modo da costruire programmi eseguibili su varie piattaforme e con ambienti grafici differenti (Windows ha un modo di visualizzare le finestre e gli altri elementi grafici diverso da quello usato da Linux o da MacOs cioè il sistema operativo della Applet). Il secondo pakage Java che gestisce gli elementi di una GUI, detto swing, è un'estensione di awt e permette la vera indipendenza dalla piattaforma. Tra i tipici oggetti contenitori il package awt rende disponibili: frame (finestra): la classica finestra costituita da un area rettangolare e da una barra del titolo panel (pannello): la forma più comune di contenitore che può essere visualizzato sullo schermo. canvas (area di disegno): una semplice superficie di disegno particolarmente utile per visualizzare immagini o per effettuare altre operazioni grafiche. I componenti sono oggetti con una propria rappresentazione grafica. Alcuni importanti componenti della GUI di Java sono: Label (etichette) Button (pulsanti) TextField (campi di testo) TextArea (aree di testo) Checkbox (caselle di controllo) Nella gerarchia di classi per i componenti ed i contenitori in Java si può notare che la radice della maggior parte degli elementi del package awt è rappresentata dalla classe astratta Component (che a sua volta eredita dalla superclasse Object, superclasse di tutti gli oggetti Java). In realtà le classi TextField e TextArea ereditano da TextComponent con radice Component. Le classi per creare controlli e la classecanvas ereditano direttamente da Component. 1 2 La classe Frame eredita da Window che eredita da Container2. Da libro Gallo-Salerno Java La programmazione a oggetti ed. Minerva Italica [UD C3] Containers
2 A differenza delle applicazioni, un Applet, non necessita di una finestra per essere eseguito infatti la finestra è quella del browser a cui si aggiunge un pannello che rappresenta l applet. La classe Applet, infatti, eredita da Panel che eredita da Container la cui radice è appunto Component. Creazione e uso dei contenitori standard La classe JFrame ha i seguenti metodi costruttori: JFrame() JFrame( Stringa ) Crea una finestra senza titolo Crea una finestra senza titolo specificato in Stringa Altri metodi che si applicano ad un oggetto della classe JFrame: setsize(larghezza, altezza) setlocation( x, y) pack() setvisible(boolean) show()) setresizable(boolean) dispose() Dimensiona la finestra Posiziona la finestra (coordinate del punto in alto a sinistra) Ottimizza le dimensioni della finestra a seconda del contenuto Per rendere visibile la finestra se true (deprecato il metodo Per rendere ridimensionabile con mouse se true Per chiudere la finestra, deallocando le risorse La classe JPanel ha il seguente metodo costruttore: JPanel () Crea un pannello per inserire componenti GUI L inserimento degli oggetti all interno dei contenitori si realizza con il metodo add() con la sintassi: oggettocontenitore.add (oggettodaaggiungere) Tale metodo è polimorfo cioè opera su argomenti di diverse classi. nb: è possibile aggiungere un componente e contemporaneamente sceglierne la posizione nel contenitore (con possibili West, North, East, South e Center o equivalenti costanti in swing) oggettocontenitore.add ( orientamento, oggettodaaggiungere ) es: nomepannello.add ( West, nomecomponente); nomepannello.add ( North, nomecomponente);
3 // esempio di Applicazione con uso di oggetti GUI in ambiente JCreator import java.awt.*; import javax.swing.*; public class Finestra { private JFrame f ; private Container c; private JPanel p; public Finestra () { // costruttore f = new JFrame("Visualizza sfondo colorato"); // crea frame o cornice invisibile c = f.getcontentpane(); // recupera il "muro grezzo" // cioè il riquadro dei contenuti senza barra dei menù // per impostare le dimensioni e la posizione: f.setsize(300,150); // misure in pixel: larghezza, altezza f.setlocation(200,100); // (0,0) angolo sup. sin p = new JPanel(); p.setbackground(color. lightgray); // sfondo del pannello colorato c.add(p); f.setvisible(true); // aggiunge il pannello // mostra il frame (dimensioni 300x150) - deprecato show() f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); // rende attiva l'icona di chiusura // nella barra del titolo public static void main(string [] args) { Finestra o = new Finestra(); // creo oggetto che "ha - un" oggetto JFrame ed un oggetto JPanel nb: setdefaultcloseoperation(jframe.flag); questo metodo permette di modificare l'azione di default di Java di continuare ad eseguire l'applicazione che ha generato il frame anche dopo aver clickato sull'apposito bottone di chiusura del frame; segue un elenco del significato del campo flag : EXIT_ON_CLOSE : terminazione del programma quando il frame viene chiuso DISPOSE_ON_CLOSE : chiude e libera il solo oggetto frame, il processo continua DO_NOTHING_ON_CLOSE : mantiene aperto il frame e continua il processo (ignoriamo l'evento) HIDE_ON_CLOSE : chiude il frame e continua l'esecuzione Per nascondere i frames: setvisible(false) - deprecato hide()
4 Creazione e uso dei componenti standard La classe JLabel : un esempio // Applicazione con uso dei componenti di una GUI // in ambiente JCreator // Uso di un pannello per introdurre // componenti JLabel // e gestione di layout con allineamento in griglia import java.awt.*; import javax.swing.*; public class MiaFinestra extends JFrame{ private Container c; private JPanel p; private JLabel l1, l2, l3, l4; public MiaFinestra () { // costruttore super ("Finestra con componenti"); // imposta il titolo del frame invisibile setsize(300,150); // per impostare le dimensioni e la posizione(misure in pixel) : setlocation(200,100); // (0,0) angolo sup. sin. setresizable(true); // per ridimensionare con mouse c = getcontentpane(); // recupera il "muro grezzo" p = new JPanel(); // per inserimento componenti con layout di tipo FlowLayout // cioè uno di seguito all altro da sinistra a destra p.setbackground (Color.lightGray); p.setlayout(new GridLayout (4,1)); // per evidenziare allineamento 4 RIGHE, 1 COLONNA JLabel l1 = new JLabel ("Etichetta con sfondo colorato"); JLabel l2 = new JLabel ("Allineata al centro", JLabel.CENTER); JLabel l3 = new JLabel ("Allineata a sinistra", JLabel.LEFT); JLabel l4 = new JLabel ("Allineata a destra", JLabel.RIGHT); l1.setbackground (Color.cyan); l1.setopaque(true); // per vedere sfondo su sfondo p.add(l2); p.add(l3); p.add(l4); p.add(l1); // aggiunge al pannello un'etichetta allineata al centro // aggiunge al pannello un'etichetta allineata a sinistra // aggiunge al pannello un'etichetta allineata a destra // aggiunge al pannello un'etichetta con sfondo colorato c.add(p); // aggiunge il pannello setvisible(true); // mostra il frame (dimensioni 300x150) setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string [] args) { MiaFinestra o = new MiaFinestra(); // creo oggetto che "ha" componenti Gui Altri metodi : String gettext() restituisce il testo dell etichetta o del JComponent settext ( Stringa ) modifica il testo dell etichetta o del JComponent int gethorizontalalignment() restituisce come intero l allineamento dell etichetta (0 o 1 o 2) sethorizontalalignment (int) modifica l allineamento dell etichetta a seconda della costante intera: JLabel.CENTER o LEFT, RIGHT, LEADING, TRAILING (per default) setfont(oggetto_classe_font) modifica il tipo di carattere dell etichetta
5 Le classi JButton, JTextField, JTextArea, JCheckBox, JRadioButton e ButtonGroup // Applicazione per illustrare creazione di componenti di una GUI in ambiente JCreator // Uso di pannello per introdurre componenti (per default con layout di tipo FlowLayout // cioè i componenti sono aggiunti uno di seguito all altro da sinistra a destra) import java.awt.*; import javax.swing.*; public class Gui2 { private JFrame f ; private Container c; private JPanel p; private JLabel l; private JButton b1, b2; private JTextField t1, t2; private JTextArea a1, a2; private JCheckBox c1, c2, c3; private ButtonGroup g; private JRadioButton rb1, rb2; // per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button public Gui2 () { // costruttore f = new JFrame("Finestra con componenti"); // crea frame invisibile f.setsize(450,330); // misure in pixel per impostare le dimensioni f.setlocation(200,100); // e la posizione con (0,0) angolo sup. sin. f.setresizable(true); // per ridimensionare con mouse c = f.getcontentpane(); p = new JPanel(); p.setbackground (Color.lightGray); // sfondo colorato l = new JLabel ("Etichetta"); b1 = new JButton (); b2 = new JButton ("Bottone"); t1 = new JTextField (30); t2 = new JTextField ("immetti il nome", 20); a1 = new JTextArea(5, 20); // senza barre a scorrimento se non si inserisce in JScrollPane a2 = new JTextArea("immetti una lista di nomi ", 5, 20); a1.append ("Dimensionata con 5 righe e 20 colonne"); c1 = new JCheckBox(); c2 = new JCheckBox("Testo"); c3 = new JCheckBox("Testo attivato", true); c1.settooltiptext("senza testo"); // per visualizzare, al passaggio del mouse, testo esplicativo g = new ButtonGroup(); // per gestire selezione rb1 = new JRadioButton("Lingua Francese", false); rb2 = new JRadioButton("Lingua Francese", true); g.add(rb1); g.add(rb2); p.add(l); // aggiunge al pannello un'etichetta con testo p.add(b1); // aggiunge al pannello un bottone colorato con etichetta p.add(b2); // aggiunge al pannello un bottone con testo p.add(t1); // aggiunge al pannello un campo di testo con ampiezza specificata p.add(t2); // aggiunge al pannello un campo di testo con inizializzazione // ed ampiezza specificata p.add(a1); // aggiunge al pannello un' area di testo con Righe e Colonne specificate p.add(a2); // aggiunge al pannello un'area di testo con inizializzazione // e Righe e Colonne specificate p.add(c1); // aggiunge al pannello una casella di controllo vuota e disattivata p.add(c2); // aggiunge al pannello una casella di controllo con stringa p.add(c3); // aggiunge al pannello una casella di controllo con stringa ed attivata p.add(rb1); // aggiunge al pannello i Radio Button p.add(rb2); c.add(p); // aggiunge il pannello f.setvisible(true); // mostra il frame (dimensioni 400x400) f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string [] args) { Gui2 o = new Gui2();
6 Altri metodi della classe JButton: String gettext() per ottenere il valore dell etichetta dell oggetto, deprecato getlabel() Altri metodi della classe JCheckBox: String gettext() restituisce il valore dell etichetta, deprecato getlabel() settext( Stringa ) imposta il valore dell etichetta, deprecato setlabel() Altri metodi delle classi che ereditano da JComponent: String gettooltiptext() restituisce il valore del testo settato con settooltiptext Altri metodi della classe JRadioButton ereditati dalla classe AbstractButton: isselected() ritorna il valore booleano che indica lo stato del radio-bottone setselected (stato) per settare lo stato del radio-bottone Posizionamento diretto di un elemento GUI o tramite gestori di layout Nel posizionamento diretto (dipendente dalle impostazioni grafiche del sistema) non abbiamo bisogno di un gestore di layout (layout manager3) e dobbiamo indicare questo fatto con l istruzione: setlayout (null); Definiremo poi le dimensioni dell elemento e lo posizioneremo mediante il metodo setbounds() con sintassi: setbounds(x,y,larghezza,altezza) // x,y dell angolo sup. sin. Per default il gestore di layout per tutti i contenitori di tipo pannello è la classe FlowLayout che aggiunge i componenti uno di seguito all altro da sinistra a destra (nello stesso ordine in cui vengono aggiunti col metodo add ): riempita la prima riga si inizia la seconda e così via. Abbiamo già fatto uso della classe GridLayout con costruttore GridLayout (numero righe, numero colonne) per posizionare i componenti nelle celle di una tabella tutte caratterizzate dalla stessa dimensione. Un altro costruttore permette di impostare anche la spaziatura verticale e quella orizzontale: GridLayout (num_righe, num_colonne, spaziatura_verticale, spaziatura_orizzontale) BorderLayout BorderLayout divide lo schermo in cinque regioni: North, East, West, South, Center. È, di default il gestore di layout per i contenitori ad alto livello come i Content Pane. BorderLayout assicura a North, South, East e West tanto spazio quanto richiedono, lo spazio rimanente viene assegnato a Center. BorderLayout può essere costruito con costruttore BorderLayout () oppure con BorderLayout (spaziatura_orizzontale, spaziatura_verticale) specificano lo spazio orizzontale e verticale tra due componenti. nb: nel package swing tali regioni vengono definite dalle costanti BorderLayout.PAGE_START, BorderLayout.LINE_START, BorderLayout.LINE_END, BorderLayout.PAGE_END e BorderLayout.CENTER rispettivamente per indicare in alto, a sinistra, a destra, in basso e centro. Oltre alle numerose classi che già awt introduceva per gestire il posizionamento, swing rende disponibile anche la classe BoxLayout per una scelta general purpose nell impilare i vari elementi. 3 Gestori di Layout (guida visuale)
7 /******************************************************************/ /* GESTIONE DI UN LAYOUT SEMPLICE MEDIANTE USO DI SWING ****/ /******************************************************************/ import javax.swing.*; import java.awt.*; public class SempliceLayout extends JFrame { //Creiamo i componenti JLabel iplabel = new JLabel("IP host", SwingConstants.LEFT); // per default a sinistra JLabel passwordlabel = new JLabel("Password", SwingConstants.LEFT); JLabel filedainviarelabel = new JLabel("File da inviare", SwingConstants.LEFT); JTextField iptext = new JTextField(20); // impostiamo numero caratteri JPasswordField passwordtext = new JPasswordField(20); // impostiamo numero caratteri JTextField filedainviaretext = new JTextField(20); // impostiamo numero caratteri JButton pulsante = new JButton("Inizia TX"); public SempliceLayout() { // costruttore dell'applicazione super("file transfer appz"); setsize(320, 150); setdefaultcloseoperation(exit_on_close); JPanel pannello = new JPanel(); // dimensioni adatte [*] // impostiamo le proprietà dei componenti iptext.seteditable(true); filedainviaretext.seteditable(true); passwordtext.setechochar('*'); // usiamo il Layout di default di JPanel di tipo FlowLayout pannello.add(iplabel); pannello.add(iptext); pannello.add(passwordlabel); pannello.add(passwordtext); pannello.add(filedainviarelabel); pannello.add(filedainviaretext); pannello.add(pulsante); setcontentpane(pannello); // rendiamo il pannello parte del nostro frame setresizable(false); // immodificabili dimensioni [*] setvisible(true); // visualizziamo il tutto public static void main(string argv[]) { new SempliceLayout();
8 /*****************************************************************************/ /* GESTIONE DI UN LAYOUT A GRIGLIA AVANZATA MEDIANTE USO DI SWING ****/ /*****************************************************************************/ import javax.swing.*; import java.awt.*; public class Layout extends JFrame { //Creiamo i componenti JLabel iplabel = new JLabel("IP host", SwingConstants.LEFT); // per default a sinistra JLabel passwordlabel = new JLabel("Password", SwingConstants.LEFT); JLabel filedainviarelabel = new JLabel("File da inviare", SwingConstants.LEFT); JTextField iptext = new JTextField(); // non ci preoccupiamo di impostare numero caratteri JPasswordField passwordtext = new JPasswordField(); JTextField filedainviaretext = new JTextField(); JButton pulsante = new JButton("Inizia TX"); // Definiamo un metodo che ci servirà per definire i limiti di layout void impostalimite(gridbagconstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; public Layout() { // costruttore dell'applicazione super("file transfer appz"); setsize(300, 120); setdefaultcloseoperation(exit_on_close); JPanel pannello = new JPanel(); // impostiamo le proprietà dei componenti iptext.seteditable(true); filedainviaretext.seteditable(true); passwordtext.setechochar('*'); //definiamo il gestore di layout GridBagLayout grigliaavanzata = new GridBagLayout(); // griglia personalizzata GridBagConstraints limite = new GridBagConstraints(); pannello.setlayout(grigliaavanzata); //definiamo i limiti di ogni componente e lo aggiungiamo al pannello impostalimite(limite,0,0,1,1,35,0); //etichetta IP host limite.fill = GridBagConstraints.NONE; limite.anchor = GridBagConstraints.EAST; grigliaavanzata.setconstraints(iplabel,limite); pannello.add(iplabel); impostalimite(limite,1,0,1,1,65,100); //campo IP host limite.fill = GridBagConstraints.HORIZONTAL; grigliaavanzata.setconstraints(iptext,limite); pannello.add(iptext);
9 impostalimite(limite,0,1,1,1,0,0); //etichetta password limite.fill = GridBagConstraints.NONE; limite.anchor = GridBagConstraints.EAST; grigliaavanzata.setconstraints(passwordlabel,limite); pannello.add(passwordlabel); impostalimite(limite,1,1,1,1,0,100); //campo password limite.fill = GridBagConstraints.HORIZONTAL; grigliaavanzata.setconstraints(passwordtext,limite); pannello.add(passwordtext); impostalimite(limite,0,2,1,1,0,0); //etichetta File da inviare limite.fill = GridBagConstraints.NONE; limite.anchor = GridBagConstraints.EAST; grigliaavanzata.setconstraints(filedainviarelabel,limite); pannello.add(filedainviarelabel); impostalimite(limite,1,2,1,1,0,100); //campo File da inviare limite.fill = GridBagConstraints.HORIZONTAL; grigliaavanzata.setconstraints(filedainviaretext,limite); pannello.add(filedainviaretext); impostalimite(limite,0,3,2,1,0,50); // Pulsante limite.fill = GridBagConstraints.NONE; limite.anchor = GridBagConstraints.CENTER; grigliaavanzata.setconstraints(pulsante,limite); pannello.add(pulsante); setcontentpane(pannello); // rendiamo il pannello parte del nostro frame setvisible(true); // Visualizziamo il tutto! public static void main(string argv[]) { Layout nf = new Layout(); GridBagLayout può organizzare interfacce grafiche complesse rendendo possibile dividere il container in una griglia e, a differenza del GridLayout, può disporre i suoi componenti in modo tale che si estendano anche oltre un unica cella, attraverso la classe GridBagConstraints.
10 /******************************************************************************/ /* SEMPLICI ETICHETTE, CAMPI ED AREE DI TESTO MEDIANTE USO DI SWING ****/ /******************************************************************************/ import javax.swing.*; import java.awt.gridlayout; public class EtichetteEcampi extends JFrame { JLabel etichetta1 = new JLabel("Allineamento a sinistra ",SwingConstants.LEFT); JLabel etichetta2 = new JLabel("Allineamento al centro",swingconstants.center); JLabel etichetta3 = new JLabel("Allineamento a destra ", SwingConstants.RIGHT); JTextField campoditesto = new JTextField("Immetti qui una stringa...",30); JTextArea areaditesto = new JTextArea("Questa é un'area di testo di\n5 righe e 30 colonne",5,30); public EtichetteEcampi() { super("etichette e campi"); setsize(350, 300); setdefaultcloseoperation(exit_on_close); JPanel pannello = new JPanel(); // impostiamo le proprietà dei componenti campoditesto.seteditable(true); areaditesto.setlinewrap(true); areaditesto.setwrapstyleword(true); // ora aggiungiamo i componenti al pannello pannello.setlayout(new GridLayout(0,1)); pannello.add(etichetta1); pannello.add(etichetta2); pannello.add(etichetta3); pannello.add(campoditesto); pannello.add(areaditesto); // rendiamo il pannello parte del nostro frame setcontentpane(pannello); setvisible(true); // Visualizziamo il tutto! public static void main(string argv[]) { EtichetteEcampi ec = new EtichetteEcampi(); nb: public GridLayout (int rows, int cols) crea un layout a griglia dove tutti i componenti sono delle stesse dimensioni. Uno tra numero rige e colonne - ma non entrtambi - può essere zero: significa che un qualsiasi numero di oggetti può essere inserito o nell'unica riga o nell'unica colonna // da
11 Etichette e bordi import java.awt.color; import java.awt.gridlayout; import javax.swing.borderfactory; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.swingconstants; public class EtichetteBordi { private JLabel label1, label2,label3; private JFrame frame; private JPanel p; public EtichetteBordi(){ label1 = new JLabel("BottomRight", SwingConstants.RIGHT); label2 = new JLabel("CenterLeft", SwingConstants.LEFT); label3 = new JLabel("TopCenter", SwingConstants.CENTER); label1.setverticalalignment(swingconstants.bottom); label2.setverticalalignment(swingconstants.center); label3.setverticalalignment(swingconstants.top); label1.setborder(borderfactory.createlineborder(color.black)); label2.setborder(borderfactory.createlineborder(color.black)); label3.setborder(borderfactory.createlineborder(color.black)); frame = new JFrame("AlignmentExample"); frame.setdefaultcloseoperation(jframe.exit_on_close); p = new JPanel(new GridLayout(3, 1, 0, 8)); // righe, colonne, pixel tra colonne, pixel tra righe // in questa applicazione, con unica colonna, // è indifferente hgap che pùò valere anche 0 p.add(label1); p.add(label2); p.add(label3); p.setborder(borderfactory.createemptyborder(8, 8, 8, 8)); // top, left, bottom, right frame.setcontentpane(p); frame.setsize(300, 200); frame.setvisible(true); public static void main(string[] args) { new EtichetteBordi(); nb: public GridLayout (int rows, int cols, int hgap, int vgap) crea un layout a griglia dove tutti i componenti sono delle stesse dimensioni e rende possibile impostare il numero di pixel tra le colonne come per il margine destro e sinistro dai bordi (horizontal gap) ed il numero di pixel tra le righe come per i margini in alto e basso dai bordi (vertical gap).
12 /** * Gui application 3AI /4/4 */ import java.awt.*; import javax.swing.*; class MioPanel extends JPanel{ public MioPanel(){ this.setpreferredsize(new Dimension(180, 150)); // per reimpostare dinamicamente public void paintcomponent(graphics g){ super.paintcomponent(g); g.setcolor(color.red); g.fillrect(20,20, 100,80); g.setcolor(color.blue); g.drawrect(30,30, 80,60); g.setcolor(color.black); g.drawstring("ciao",50,60); class Bottone extends JPanel{ private JButton b; public Bottone(){ b = new JButton("label del bottone"); b.setbackground(color.white); b. setpreferredsize(new Dimension(130, 15)); this.add(b); // oggetto corrente public class Gui { private JFrame f; private Container c; private MioPanel p; // pannelli personalizzati private Bottone p2; public Gui(){ f = new JFrame("Due pannelli"); // crea un nuovo JFrame Inizialmente invisibile con titolo c = f.getcontentpane(); // recupera il "muro grezzo" p = new MioPanel(); // crea pannello personalizzato adattabile alle dimensioni della finestra p2 = new Bottone(); // crea altro pannello personalizzato adattabile alle dimensioni di bottone e finestra p2.setbackground(color.blue); c.setlayout(new BorderLayout()); // scelta di Layout che distingue tra alto, basso, destra, sinistra e centro c.add(p,borderlayout.center); // al centro il pannello con disegno c.add(p2,borderlayout.page_end); // in basso il bottone (per retrocompatibiltà anche SOUTH) f.pack(); // ottimizza le dimensioni della finestra f.setlocation(400,150); f.setvisible(true); // mostra il JFrame f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string[] v){ Gui gui = new Gui();
13 // Lo stesso esempio di Applicazione con uso GUI già usato per introdurre componenti GUI // in un pannello. Posizionamento tramite gestori di layout: impilando in verticale import java.awt.*; import javax.swing.*; public class Gui2 { private JFrame f ; private Container c; private JPanel p; private JLabel l; private JButton b1, b2; private JTextField t1, t2; private JTextArea a1, a2, a3; private JScrollPane sp; private JCheckBox c1, c2, c3: private ButtonGroup g; private JRadioButton rb1, rb2; // con barre a scorrimento inserendo JTextArea in JScrollPane // per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button public Gui2 () { // costruttore f = new JFrame("Finestra con componenti"); // crea frame invisibile // per impostare le dimensioni e la posizione: f.setsize(450,330); // misure in pixel f.setlocation(200,100); // (0,0) angolo sup. sin. f.setresizable(true); // per ridimensionare con mouse c = f.getcontentpane(); // recupera il "muro grezzo" p = new JPanel(); p.setbackground (Color.lightGray); // sfondo colorato p.setlayout (new BoxLayout (p, BoxLayout.PAGE_AXIS)); // impila gli elementi in verticale nel pannello l = new JLabel ("Etichetta"); b1 = new JButton (); b2 = new JButton ("Bottone"); b1.setbackground (Color.cyan); b1.settext("bottone con etichetta"); // imposta il valore dell etichetta ( deprecato setlabel (testo) ) t1 = new JTextField (30); t2 = new JTextField ("immetti il nome", 20); a1 = new JTextArea(5, 20); a1.append("dimensionata con 5 righe e 20 colonne"); a2 = new JTextArea("immetti una lista di nomi ", 5, 20); a3 = new JTextArea("immetti un commento personale ", 2, 15); sp = new JScrollPane(a3); // per vedere barre a scorrimento in JTextArea c1 = new JCheckBox(); c2 = new JCheckBox("Testo"); c3 = new JCheckBox("Testo attivato", true); c1.settooltiptext("senza testo"); // per visualizzare, al passaggio del mouse, testo esplicativo // Per creare pulsanti di opzione (uno solo selezionabile) detti Radio Button g = new ButtonGroup(); // per gestire selezione rb1 = new JRadioButton("Lingua Francese", false); rb2 = new JRadioButton("Lingua Francese", true); g.add(rb1); g.add(rb2); p.add(l); // aggiunge al pannello un'etichetta con testo p.add(b1); // aggiunge al pannello un bottone colorato con etichetta p.add(b2); // aggiunge al pannello un bottone con testo p.add(t1); // aggiunge al pannello un campo di testo con ampiezza specificata p.add(t2); // aggiunge al pannello un campo di testo con inizializzazione ed ampiezza specificata p.add(a1); // aggiunge al pannello un' area di testo con Righe e Colonne specificate p.add(a2); // aggiunge al pannello un'area di testo con inizializzazione e Righe e Colonne specificate p.add(sp); // aggiunge al pannello un Pannello a scorrimento che contiene // un'area di testo con inizializzazione e Righe e Colonne ridotte per visualizzare barre a scorrimento p.add(c1); // aggiunge al pannello una casella di controllo vuota e disattivata
14 p.add(c2); // aggiunge al pannello una casella di controllo con stringa p.add(c3); // aggiunge al pannello una casella di controllo con stringa ed attivata p.add(rb1); // aggiunge al pannello i Radio Button p.add(rb2); c.add(p); // aggiunge il pannello f.setvisible(true); // mostra il frame (dimensioni 400x400) f.setdefaultcloseoperation ( JFrame.EXIT_ON_CLOSE); public static void main(string [] args) { Gui2 o = new Gui2(); nb: per impilare in orizzontale BoxLayout (nomecontenitore, BoxLayout.LINE_AXIS) Impilando gli elementi in verticale nel pannello Impostando 6 Righe e 2 colonne (con solo 12 componenti) Default: un componente dopo l altro
15 Lo stesso modo di introdurre componenti GUI si può realizzare con Applet o piuttosto JApplet se si usano JComponent. Vediamo un esempio che crea una finestra diversa da quella del browser (confrontare con l applicazione Gui): // esempio di JApplet con uso dei componenti di una GUI (chiusura finestra browser per uscire) import java.awt.*; import javax.swing.*; import java.applet.*; public class GuiA extends JApplet { public void init() { JFrame f = new JFrame("Finestra con componenti"); // crea frame invisibile f.setsize(300,150); f.setlocation(200,100); // misure in pixel per impostare le dimensioni // e la posizione con (0,0) angolo sup. sin. f.setresizable(true); // per ridimensionare con mouse Container c = f.getcontentpane(); JPanel p = new JPanel(); p.setbackground (Color.gray); // recupera il "muro grezzo" // sfondo colorato p.setlayout(new GridLayout(4,4)); // per evidenziare allineamento JLabel l1 = new JLabel ("Etichetta con sfondo colorato"); JLabel l2 = new JLabel ("Allineata al centro", JLabel.CENTER); JLabel l3 = new JLabel ("Allineata a sinistra", JLabel.LEFT); JLabel l4 = new JLabel ("Allineata a destra", JLabel.RIGHT); l1.setbackground (Color.cyan); l1.setopaque(true); p.add(l2); p.add(l3); p.add(l4); p.add(l1); // vedere sfondo su sfondo // aggiunge al pannello un'etichetta allineata al centro // aggiunge al pannello un'etichetta allineata a sinistra // aggiunge al pannello un'etichetta allineata a destra // aggiunge al pannello un'etichetta con sfondo colorato c.add(p); // aggiunge al frame il pannello colorato f.setvisible(true); // mostra il frame (dimensioni 300x150) // NB: si noti come per ragioni di sicurezza sia proibito l uso di // f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); Nel codice HTML: <object code ="GuiA.class" width= "300" height= "0"></object> le dimensioni obbligatorie pur se nulle, qui sono scelte in modo da permettere di leggere completamente, eseguendo in ambiente JCreator, il titolo della cornice del visualizzatore della Java Applet Window con messaggio di Applet avviato o non avviato.
16 NB: Un applet dunque può aprire un'altra finestra ma compare automaticamente un avviso anche solo come piccola icona di allerta in alto a sinistra della nuova finestra che ricorda come la Java Applet Window non sia mai completamente invisibile. nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa cartella del bytecode (classes). Si noti che,scegliendo come progetto Basic Java Applet si crea nella sottocartella classes la seguente pagina <html> <head> </head> <body bgcolor="000000"> <center><applet code width height </applet> </center> </body> = "NomeClasse.class" = "500" = "300" > </html> con uso di tag obsoleto <applet></applet> Esercizio: Creare un applet che disegni il cruscotto di un automobile in una finestra separata. Nel cruscotto devono apparire 4 bottoni con testo: Freccia Sx, Freccia Dx, Freno Manuale, Avvia Motore un etichetta con testo Luci con associate 3 caselle opzione (esclusiva) con testo posizioni, anabbaglianti, abbaglianti, tutte non attivate un etichetta carburante ed un JTextField largo 30 pixel 150 pixel 570 pixel
17 Soluzione: // esempio di JApplet con uso contenitori e componenti GUI import java.awt.*; import javax.swing.*; import java.applet.*; public class Cruscotto extends JApplet { public void init() { JFrame f = new JFrame ("Cruscotto di un auto"); f.setsize (570, 150); f.setlocation (100,100); f.setresizable(true); // con mouse ridimensionabile Container c = f.getcontentpane(); // recupera il "muro grezzo" ButtonGroup luci = new ButtonGroup(); JRadioButton rb1 = new JRadioButton("posizioni", false); JRadioButton rb2 = new JRadioButton("anabbaglianti", false); JRadioButton rb3 = new JRadioButton("abbaglianti", false); luci.add(rb1); luci.add(rb2); JButton FrecciaSx = new JButton ("Freccia Sx"); JButton FrecciaDx = new JButton ("Freccia Dx"); JButton FrenoManuale = new JButton ("Freno Manuale"); JButton AvviaMotore = new JButton ("Avvia Motore"); JTextField carburante = new JTextField (30); c.setlayout (new GridLayout (3,4,10,10)); c.add(frecciasx); c.add(frecciadx); c.add(avviamotore); c.add(frenomanuale); c.add(new Label("Luci")); c.add(rb1); c.add(rb2); c.add(rb3); c.add(new Label("Carburante")); c.add(carburante); f.setvisible(true); Nel codice HTML: <object code ="Cruscotto.class" width= "0" height= "0"></object> nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa cartella del bytecode (classes).
18 I Canvas Tra i vari contenitori Java il Canvas (area di disegno o tela) è una semplice superficie di disegno particolarmente utile per visualizzare immagini o per effettuare altre operazioni grafiche. Un oggetto di tipo Canvas è semplicemente una porzione rettangolare di schermo, una specie di pannello che possiede un proprio metodo paint() che, pur diverso dall omonimo metodo di un Applet, usa anch esso oggetti della classe Graphics ed è richiamato dal sistema in fase di creazione e aggiornamento in modo che l oggetto Graphics associato possa aggiornarsi. Una istanza della classe Canvas non è molto utile: riceve eventi da tastiera e da mouse, ma non li tratta, ed il metodo paint() non disegna alcunché. Generalmente la classe Canvas è usata solo come base per subclassi, che possono generare oggetti più utili: una subclasse di Canvas generalmente farà almeno un override del metodo paint() e possibilmente anche dei metodi di gestione degli eventi come quelli del mouse e della tastiera. Quando il contenuto del canvas dovrà essere modificato al di fuori del metodo paint(), sarà possibile richiamare il contesto grafico con i metodi getgraphics(). Vedremo come questi metodi possono essere usati per i canvas creando ad esempio un bottone di forma personalizzata e colore modificato da eventi Pur se è possibile disegnare direttamente in ogni Component, ed è comune disegnare direttamente su applet e finestre, è di solito meglio collocare ogni operazione di disegno nelle sottoclassi del Canvas: nei casi in cui sia necessario disegnare su un applet che contiene anche dei bottoni, l'uso di un canvas è pressochè inevitabile. // esempio di Applicazione con uso GUI (necessita una finestra o JFrame) // Per disegnare uso di classe che eredita da Canvas import java.awt.*; import javax.swing.*; public class Graf{ public Graf () { JFrame f = new JFrame("Finestra"); // crea frame invisibile Container c = f.getcontentpane(); // recupera il "muro grezzo" Disegno d = new Disegno(); // classe esterna che eredita da Canvas c.add (d); f.setsize(300,180); // per impostare le dimensioni e la posizione: misure in pixel f.setlocation(200,100); // (0,0) angolo sup. sin. f.setresizable(true); // per ridimensionare (per default non ridimensionabili) con mouse f.setvisible(true); // mostra il frame (dimensioni 300x150) f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string [] args) { Graf ogg = new Graf(); // fine classe principale
19 // classe esterna eventualmente nello stesso file Graf.java class Disegno extends Canvas { public void paint(graphics g) { g.setcolor(color.red); g.fillrect(20,20,100,80); // rettangolo pieno g.setcolor(color.blue); g.drawrect(30,30,80,60); // linea rettangolare g.setcolor(color.black); g.drawstring("ciao", 50,60); Font f1 = new Font("Times", Font.PLAIN, 20); g.setfont(f1); g.drawstring("ciao", 200,60); // cambiare font // per recuperare le proprietà del font f1 = g.getfont(); int size = f1.getsize(); int style = f1.getstyle(); String name = f1.getname(); g.drawstring("font di dimensioni " + size, 50,140); System.out.println("Font di dimensioni "+ size +" stile " + style + " e nome " + name); // fine classe che eredita da Canvas Esercizio: Creare un Applet che disegni un automobile in modo stilizzato: 1) direttamente nella finestra del browser. 2) con un canvas in una finestra separata. Si costruisca una classe AutoC con gli opportuni metodi grafici già usati per disegnarla direttamente nella finestra del browser.
20 Soluzione: esempio di Applet che usa canvas in una finestra separata import java.awt.*; import java.applet.*; import javax.swing.*; public class AutoC extends JApplet { Auto A; public void init() { JFrame f1 = new JFrame ("Disegna auto"); A = new Auto(); // istanza che eredita da Canvas f1.setsize (500, 420); f1.setlocation (50,50); f1.setresizable(true); // con mouse ridimensionabile Container c =f1.getcontentpane(); c.add(a); f1.setvisible(true); class Auto extends Canvas { public void paint(graphics g) { Font f = new Font("Times Roman", Font.BOLD, 20); g.setfont(f); g.filloval(120, 220, 60,60); // una ruota piena g.filloval(320, 220, 60,60); // altra ruota piena g.setcolor(color.blue); // carrozzeria blu g.drawrect(50, 150, 400, 70); g.drawline(170,150,200,100); g.drawline(330,150,300,100); g.drawline(300,100,200,100); g.setcolor(color.yellow); // luci gialle g.fillrect(50, 170, 20, 30); g.setcolor(color.red); // luci rosse g.fillrect(430, 150, 20, 20); g.setcolor(color.cyan); // testo cyan g.drawstring("automobile", 200, 350); Codice HTML: <html> <head><title>disegno di un Auto </title></head> <body> <object code ="AutoC.class" width= "500" height= "150">></object> </body> </html> nb: per eseguire la pagina html con opzione Run in JCreator, salvare tale pagina web nella stessa cartella del bytecode (classes).
21 Gli Eventi Quando l utente di una GUI digita caratteri o usa il mouse o un componente dell interfaccia grafica, il gestore delle finestre di Java invia una comunicazione al programma per segnalare che si è verificato un evento. Esistono classi d ascolto di eventi (event listener) per permettere ad un programma di indicare quali eventi gradisce ricevere. Ogni programma dovrà creare un oggetto per ognuna delle classi cui è interessato; tali oggetti prendono il nome di ascoltatori (oggetto di una classe di ascolto). La classe di ascolto deve implementare almeno una interfaccia di ascolto (interfacce di tipo listener). Un ascoltatore di eventi è un oggetto di una classe di ascolto che implementa almeno una interfaccia di ascolto. Tali interfacce sono contenute nel package java.awt.event che deve essere importato. Per creare un ascoltatore bisogna conoscere l origine dell evento che può essere l intera applet o una sua parte. Per origine dell evento si intende il contenitore o il componente che può generare l evento (ad esempio un pulsante è l origine dell evento tipo clic su pulsante ). Eventi del mouse Esempio con gestione eventi del mouse: // ClickMe.java import java.applet.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; // classe di ascolto public class ClickMe extends JApplet implements MouseListener { // tipo di evento ad esempio // pressione del mouse private Spot spot = null; private static final int RADIUS = 7; public void init() { addmouselistener(this); // per collegare ascoltatore all origine dell evento: tutta l applet public void paint(graphics g) { //draw a black border and a white background g.setcolor(color.white); g.fillrect(0, 0, getsize().width - 1, getsize().height - 1); //oppure g.fillrect(0, 0, getwidth() - 1, getheight()- 1); g.setcolor(color.black); g.drawrect(0, 0, getsize().width - 1, getsize().height - 1); //oppure g. drawrect(0, 0, getwidth() - 1, getheight()- 1); //draw the spot g.setcolor(color.red); if (spot!= null) { g.filloval(spot.x - RADIUS, spot.y - RADIUS, RADIUS * 2, RADIUS * 2);
22 public void mousepressed(mouseevent event) { if (spot == null) { spot = new Spot(RADIUS); spot.x = event.getx(); spot.y = event.gety(); repaint(); public void mouseclicked(mouseevent event) { public void mousereleased(mouseevent event) { public void mouseentered(mouseevent event) { public void mouseexited(mouseevent event) { // tipo evento: pressione del mouse // altri metodi dell interfaccia di ascolto // per evitare di scrivere tali segnature // di metodi si usa classe Adapter che // implementa interfaccia MouseListener // Spot.java public class Spot { public int size; public int x, y; public Spot(int intsize) { size = intsize; x = -1; y = -1; Nel codice HTML le dimensioni obbligatorie non saranno nulle: con codice più datato (IE): <object code ="GuiA.class" width= "200" height= "100">></object> con codice HTML che carica ed esegue Applet con "Java Plug in" per consentire al browser di usare un interprete Java esterno (più aggiornato) e adatta anche a Mozilla FireFox ed altri browser che non supportano il tag <object>: <html> <head><title>uso Eventi</title></head> <body> <p>carica ed esegue Applet con uso di Java Plug-in (anche per NN versioni precedenti alla 6): <p>appare uno spot rosso nel punto dove fai click col mouse <p><object classid="clsid:8ad9c e-11d1-b3e f499d93" width="200" height="100"> <param name="code" value="clickme.class"> <param name="type" value="application/x-java-applet;version=1.6"> <comment><embed type="application/x-java-applet" width="200" height="100" code="clickme.class"> </embed> </comment> </object> </body> </html> NB: getwidth() e getheight() per recupero dimensioni senza creare oggetto Dimension con getsize()
23 Esempio con gestione eventi del mouse con adattatore (classe di raccordo Adapter) che evita di dover scrivere tutte le segnature dei metodi dell'interfaccia di ascolto : // Pallini.java versione Applet import java.applet.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Pallini extends JApplet{ private int xp,yp; public void init() { MiaClasseAscoltoMouse A1 = new MiaClasseAscoltoMouse (); addmouselistener (A1); // lega la classe di ascolto all origine dell evento: cioè // tutta l applet (è sottinteso this : manca oggetto origine) public void paint(graphics g) { g.setcolor(color.red); g.filloval(xp,yp,20,20); public void test() { // per test in ambiente JCreator int x = getlocationonscreen().x; // ritorna l ascissa del punto int y = getlocationonscreen().y; // ritorna l ordinata del punto System.out.println( "punto (" + xp + "," + yp +")" ); // classe interna cioè innestata non statica private class MiaClasseAscoltoMouse extends MouseAdapter { public void mousepressed (MouseEvent e) { xp = e.getx(); // accede alla variabili istanza xp e yp della classe esterna yp = e.gety(); // recupera gli attributi dell oggetto di tipo Point puntato dal mouse // cioè le coordinate x ed y repaint(); test(); // per visualizzare coordinate // fine classe Pallini Con codice HTML: <html> <head><title>uso Classe Adapter</title></head> <body> Se premi con il mouse (all'interno di una zona) compare un pallino rosso <br> <object code ="Pallini.class" width = "500" height = "400"></object> </body> </html> NB: per estrarre coordinate sullo schermo getlocationonscreen() della classe java.awt.component può essere invocato per recuperare le coordinate del punto in alto a sinistra ad esempio dell applet; il metodo ritorna infatti un oggetto di tipo Point con attributi x ed y ed è applicabile al componente corrente
24 /** * * Pallini application * classi /4/14 */ import java.awt.event.*; import java.awt.*; import javax.swing.*; public class Pallini extends JPanel{ private int x,y; private JFrame f ; public Pallini() { f= new JFrame(); f.setcontentpane(this); MiaClasseAscoltoMouse A1 = new MiaClasseAscoltoMouse (); addmouselistener (A1); // lega la classe di ascolto all origine dell evento: cioè tutta // l applicazione (this è sottinteso) f.settitle("sposta e Premi Mouse"); f.setlocation(300,300); f.setsize(320,300); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public void paintcomponent(graphics g) { // super.paintcomponent(g); // senza ricostruzione dello sfondo: non aggiorna g.setcolor(color.red); g.filloval(x,y,20,20); private class MiaClasseAscoltoMouse extends MouseAdapter { // classe interna public void mousepressed (MouseEvent e) { x = e.getx(); // accede alla variabili istanza x e y della classe y = e.gety(); repaint(); public static void main(string[] args) { new Pallini(); // fine applicazione Pallini
25 Eventi di azione (Interfaces ActionListener, Classes ActionEvent) Sono generati quando si premono bottoni, si selezionano voci di menù, si preme invio mentre si scrive in un campo di testo. In awt sono generati da componenti delle classi Button, TextField, List e MenuItem Molti controlli Swing oltre a JButton generano eventi che possono essere catturati da un actionlistener cioè sono sorgente di eventi ActionEvent Eventi di azione sono provocati dall'utente che agisce su un componente (click su un pulsante); vale per gli oggetti istanza delle classi JButton, JCheckBox, JComboBox, JRadioButton (controlli derivati da AbstractButton) e JTextField. I seguenti eventi ad esempio notificano un evento azione: Quando si premere INVIO in un campo di testo Quando si seleziona una checkbox, un radiobutton o una voce in un combobox Quando si seleziona una voce di un menu o si clicca su un bottone Esempio di struttura di applicazione con gestione eventi generati4 da interazione con interfaccia grafica: un pulsante (parte della GUI) è origine dell evento (di azione) tutta la classe è ascoltatore dell evento (di azione) esiste un solo metodo nell interfaccia import java.awt.event.*; import java.awt.*; import javax.swing.*; public class NomeClasse implements ActionListener { // classe ascoltatore // con interfaccia per eventi di azione private JFrame f; private Container c; private JPanel p; private JButton b; public NomeClasse(){ // costruttore f = new JFrame ("Cambio di colore"); c = f.getcontentpane(); p = new JPanel(); b = new JButton("Premi"); b.addactionlistener (this); // lega la classe di ascolto cioè l applicazione stessa // all origine dell evento cioè il pulsante b.setbackground (Color.red); p.add(b); c.add(p); f.setlocation(200,200); f.setsize(250,70); f.setbackground(color.white); f.setvisible(true); f.setdefaultcloseoperation(jframe.exit_on_close); // senza esplicita gestione di eventi di finestra 4 Altre applicazioni a eventi in Java: applicazioni embedded basate su interrupt (ad esempio i driver di dispositivo) ed applicazioni distribuite basate su scambio asincrono di eventi (ad esempio quelle di network management)
26 // implemento il metodo dell interfaccia di ascolto public void actionperformed (ActionEvent e) { // unico metodo da ridefinire b.setbackground (Color.cyan); // cambia colore di sfondo del bottone public static void main (String [] args) { NomeClasse o = new NomeClasse (); // fine applicazione Eventi metodi utili Object getsource() restituisce la componente su cui si è verificato l evento e si può scoprire con instanceof a quale classe appartiene. getselectedobjects()[0] ritorna array (length 1) con label o null se non selezionato; usato con operatore di cast (String); in alternativa, per classe Checkbox, anche gettext() ActionEvent: String getactioncommand() se l evento è generato su un TextField restituisce la stringa contenuta nel TextField in alternativa a gettext() KeyEvent: char getchar() char getkeychar() int getkeycode() restituisce il carattere associato al tasto che ha generato l evento restituisce il numero corrispondente (ad esempio il tasto ESC è 27) MouseEvent: int getx(), int gety() restituiscono le coordinate del cursore Definizione e Registrazione di Listeners Definizione, due possibilità implementando il Listener class MyXXXListener implements XXXListener { // definizione dei metodi definiti da XXXListener estendendo l adapter class MyXXXListener extends XXXAdapter { // override i metodi definiti da XXXAdapter Registrazione: ogni event source ha un metodo per registrare un corrispondente listener addxxxlistener (XXXListener listenerobject)
27 È possibile installare uno stesso ascoltatore, ad esempio, per diversi bottoni di una toolbar il vantaggio risiede nel fatto che i diversi bottoni hanno lo stesso ascoltatore (invece che più ascoltatori separati che fanno la stessa cosa) Esercizio: pulsanti con stessa classe di ascolto e stesso metodo actionperformed() // esempio di Applet con gestione eventi della GUI // Uso di due pulsanti import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.applet.*; public class Pulsanti extends JApplet { JTextField T = new JTextField (30); JButton B1 = new JButton("sinistro"); JButton B2 = new JButton("destro"); JFrame f1 = new JFrame("Pulsanti"); public void init() { f1.setsize (400, 200); f1.setlocation (50,50); f1.setresizable(true); // con mouse ridimensionabile f1.setlayout(new GridLayout (1,3,50,0)); Container c = f1.getcontentpane(); // recupera il "muro grezzo" B1.addActionListener (new Ascolta()); B2.addActionListener (new Ascolta()); c.add(b1); c.add(t); c.add(b2); f1.setvisible(true); private class Ascolta implements ActionListener { public void actionperformed (ActionEvent e) { String Bottone = e.getactioncommand(); // testo mostrato da pulsante if (Bottone.equals ("sinistro") ) T.setText("pulsante sinistro"); else T.setText("pulsante destro"); // fine applet Problema: scrivere un ascoltatore (listener) che alla pressione di bottoni diversi mostri il contenuto della JTextField inserita nella finestra istanza dell'applicazione MyFrame L ascoltatore deve aver accesso al riferimento a quel JTextField di quella particolare istanza Prima soluzione: si può utilizzare una classe interna come ActionListener Tecnica accettabile se l ascoltatore fà poco altrimenti la classe cresce sensibilmente in dimensioni Svantaggio: si accorpano due classi che rappresentano due aspetti concettualmente diversi Seconda soluzione: si può progettare l ascoltatore prevedendo un costruttore che prende in ingresso il riferimento alla finestra contenente il bottone. La classe resta esterna ma può accedere a tutti gli oggetti della finestra (a patto che questi non siano privati)
28 Un Listener per N Controlli Primo caso: uso classe Listener interna cioè innestata non statica public class MyFrame extends JFrame { //... JButton up= new JButton( Up ); JButton down= new JButton( Down ); JButton random= new JButton( Random ); Listener ascoltatore = new Listener(); public MyFrame() {... up.addactionlistener(ascoltatore); down.addactionlistener(ascoltatore); random.addactionlistener(ascoltatore); //... // componenti attivi della stessa natura private class Listener implements ActionListener { // classe interna public void actionperformed (ActionEvent e) { Object src = e.getsource(); // si individua l oggetto mittente della segnalazione if (src == up) { codice associato alla pressione del bottone Up else if (src == down) { codice associato alla pressione del bottone Down else if (src == random) { codice associato alla pressione del bottone Random Se i componenti sono di diversa natura, ad esempio un pulsante ed un campo di testo, entrambi in grado di generare un evento di azione, il seguente codice può essere utile ad intercettare il mittente della segnalazione : public void actionperformed (ActionEvent evt){ Object src = evt.getsource(); // si individua il mittente della segnalazione if (src instanceof JTextField) funzionecampoditesto(); // scelta del giusto gestore dell'evento else if (src instanceof JButton) funzionepulsante(); Quando si usano classi esterne, è possibile capire il componente che ha notificato l evento associando ai diversi componenti un diverso valore della proprietà actioncommand nb: but[i]=new JButton (mess[i]); but[i].settooltiptext (mtool[i]); but[i].setactioncommand (mtool[i] ); // per modificare la stringa identificativa dell oggetto // registrato (associato) al gestore d evento e.getactioncommand () ritorna String default l etichetta associata al bottone (mess[i])
29 Secondo caso: classe Listener esterna. Nell esempio seguente i possibili diversi valori della proprietà actioncommand sono memorizzati come costanti della classe ascoltatore Listener esterna public class MyFrame extends JFrame { //... JButton up= new JButton( Up ); JButton down= new JButton( Down ); JButton random= new JButton( Random ); Listener ascolt = new Listener(); public MyFrame() { //... up.addactionlistener(ascolt); up.setactioncommand(ascolt.upopt); down.addactionlistener(ascolt); down.setactioncommand(ascolt.downopt); random.addactionlistener(ascolt); random.setaction Command(ascolt.RANDOMOPT); //... // classe esterna public class Listener implements ActionListener { public final static String UPOPT = Up ; // costanti public final static String DOWNOPT = Down ; public final static String RANDOMOPT = Random ; public void actionperformed(actionevent e) { String com = e.getactioncommand(); // recupero della stringa-etichetta associata al bottone if (com == UPOPT) upopt(); else if (com == DOWNOPT) downopt(); else if (com == RANDOMOPT) randomopt(); private void upopt() {... private void randomopt(){... private void downopt(){... Confronto soluzioni: In senso assoluto, le prestazioni migliori si ottengono usando l'implementazione diretta dell'interfaccia-ascoltatore, poiché non sono generate né classi né oggetti ulteriori, rispetto all'unica concretizzazione del Tipo ascoltatore. Le classi interne hanno il pregio di consentire una migliore gestione della struttura interna dell'oggetto (comportamenti adatti in ambito OO), appesantendo il caricamento dell'applicazione di quel (tanto o poco) necessario al ClassLoader per caricare e risolvere un certo numero di classi in più, rispetto alla soluzione dell'implementazione diretta. Quale che sia la scelta adottata, ciò che importa è la consapevolezza degli effetti.
30 Esercizi non risolti Esercizio (non risolto): realizzare un'applicazione grafica con dimensione della finestra 200x200 pixel come da layout in Fig.1 Fig. 1: GUI da progettare Fig. 2: Effetto che si vuole premendo il pulsante Red Alla pressione di ogni pulsante si vuole che lo sfondo cambi colore come da Fig.2 Esercizio (non risolto): realizzare un'applet EuroConvertitore implementando sia TextListener sia FocusListener Esercizio: progettare un pannello che sia maschera di input che consenta all utente di : inserire articoli (e relativo prezzo), sia in lire che in euro avere sempre sott occhio il totale, sia in lire che in euro poter salvare su file, in qualunque momento, l elenco degli ordini inseriti. Di seguito realizzare l'applicazione di test che crea una finestra di dimensioni 300x300 pixel e permette di visualizzare tale maschera col layout di figura Esercizio: prenotazione di biglietto di sola andata per una data destinazione con soluzione online
31 Progetto con array (senza soluzione) Progettare un applicazione in Java che presenti all utente una finestra (simile a quella in figura) con la possibilità di gestire un array di interi; la pressione di ogni bottone determinerà una delle seguenti elaborazioni: Reset Riempimento con valori generati casualmente e visualizzazione nell area di testo sulla destra Riempimento con valori decrescenti Ricerca del valore massimo scritto a fondo pagina Ordinamento non decrescente (Sort) Ricerca del valor medio scritto a fondo pagina Ricerca della prima occorrenza di un numero digitato da Dialog box con scrittura a fondo pagina della posizione o messaggio di avviso dell esito negativo su Dialog box Visualizzazione dei valori originari
32 Lettura da file di testo con Scanner, visualizzazione in area di testo, salvataggio di modifiche // lettura da file con visualizzazione in area di testo // modifica del testo // salvataggio su file del contenuto dell'area di testo import java.io.*; import java.util.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; class GUI { private JTextArea ta = new JTextArea(); private String sl; public void leggifile() { // LETTURA da file di testo try { FileReader fr = new FileReader("FileIni.txt"); Scanner sc = new Scanner(fr); while(sc.hasnext()) { ta.append(sc.nextline()); ta.append("\n"); fr.close(); // chiusura File catch (IOException e) { public void scrivifile() { // SCRITTURA su file di testo try { FileWriter fw = new FileWriter("FileOut.txt"); PrintWriter out = new PrintWriter(fw); sl = ta.gettext(); out.print(sl); fw.close(); // chiusura File catch (IOException e) { // salva in String tutto il testo public void visualizza(){ JFrame f = new JFrame("Finestra con area di testo"); Container c = f.getcontentpane(); JPanel p = new JPanel(); JButton b1 = new JButton ("salva"); JButton b2 = new JButton ("cancella"); b1.addactionlistener (new mioascoltatore()); b2.addactionlistener (new mioascoltatore()); p.add (b1); p.add (b2); p.setpreferredsize(new Dimension(180, 35)); ta.seteditable (true); JScrollPane listpane = new JScrollPane(ta); listpane.setpreferredsize(new Dimension(180, 120)); c.setlayout(new FlowLayout()); c.setpreferredsize(new Dimension(280, 180)); c.add(p); c.add(listpane); f.pack(); f.setvisible(true); // gestione eventi di azione //Layout the content pane
33 // classe interna class mioascoltatore implements ActionListener { public void actionperformed (ActionEvent ev) { String Bottone = ev.getactioncommand(); if (Bottone.equals ("salva") ) scrivifile(); else if (Bottone.equals ("cancella") ) ta.settext (""); // testo mostrato da pulsante // fine class GUI public class EsempioEventi { public static void main(string[] args) { GUI o = new GUI(); o.leggifile(); o.visualizza(); // fine applicazione che usa class GUI Effetto alla pressione del bottone cancella : Effetto di modifiche (uso Ctr C e Ctr V per copia/incolla): Effetto alla pressione del bottone salva : salvataggio su file di testo FileOut.txt Testo : pagina iniziale Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Modifica Attività: migliorare il progetto prevedendo uso di dialog box per scegliere il nome del file
34 Gestione Thread : scritta scorrevole che si modifica da campo di testo Esercizio: realizzare un applicazione con una scritta scorrevole che si modifica da campo di testo con uso di contenitori/componenti Swing evitando sfarfallio. Possibile soluzione: si possono inserire due PANNELLI (in un Container impilando in verticale); il secondo per disegnare con interfaccia Runnable; gestione di evento di azione con interfaccia tipo ActionListener associata al campo di testo (alla pressione di INVIO) per cancellare il testo stesso. Nella colonna di destra le modifiche per gestire la possibilità che la scritta scorra per tutta la larghezza della cornice anche se l'utente ridimensiona la finestra. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestoS implements ActionListener { private String nome; private JTextField t; private MioPanel disegno; private JPanel p; private JFrame f ; private Container c; private JLabel l; public TestoS() { // costruttore nome = "a tutti"; f = new JFrame ("Saluto"); c = f.getcontentpane(); c.setlayout (new BoxLayout (c, BoxLayout.PAGE_AXIS)); // impila gli elementi in verticale // nel Container p = new JPanel(); l = new JLabel ("Digita il tuo nome"); t = new JTextField(nome, 10); t.setforeground(color.red); // testo rosso t.setbackground(color.lightgray); // sfondo grigio chiaro per la casella di testo t.addactionlistener(this); disegno = new MioPanel(t); p.add(l); p.add(t); c.add(p); c.add(disegno); f.setsize(200,200); // con f.pack() bisogna ingrandire la finestra per vedere il disegno f.setlocation(0,0); // se non se ne impostano le dimensioni f.setresizable(false); f.setresizable(true); f.setvisible(true); Thread runner = new Thread (disegno); runner.start(); // richiama il metodo run() del thread disegno f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public void actionperformed(actionevent e) { t.settext(""); // alla pressione di INVIO public static void main(string [] args) { new TestoS(); // fine applicazione TestoS
35 // classe esterna class MioPanel extends JPanel implements Runnable { private String nome; private JTextField testo; private int Xpos; private String nome; private JTextField testo; private int Xpos; public MioPanel (JTextField t) { testo = t; setforeground(color.black); // scrive in nero public MioPanel (JTextField t) { testo = t; setforeground(color.black); // scrive in nero // larghezza scelta come // massimo valore x nello spostamento [*] public void run () { while (true) { for (Xpos =0; Xpos<getWidth(); Xpos++) { // metodo obbligatorio per eseguire il thread public void run () { while (true) { for (Xpos =0; Xpos<150; Xpos++) { repaint(); try{ Thread.sleep(80); catch(interruptedexception ie) { return; repaint(); try{ Thread.sleep(80); catch(interruptedexception ie) {return; public void paintcomponent(graphics g) { super.paintcomponent(g); nome = testo.gettext(); g.drawstring("ciao " + nome, Xpos, 50); // scelta dell'ordinata in modo da vedere meglio la scritta All'inizio la scritta è Ciao a tutti nb: l'uso di una tela (oggetto di classe che estende Canvas) disegnando con metodo paint() causa maggior effetto "flicker" o sfarfallio.
36 Confronto: scritta scorrevole che si modifica da campo di testo (unico thread associato al main) import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SenzaThread implements ActionListener { private String nome; private JTextField t; private MioPanel disegno; private JPanel p; private JFrame f ; private Container c; private JLabel l; public SenzaThread() { // costruttore nome = "a tutti"; f = new JFrame ("Saluto"); c = f.getcontentpane(); c.setlayout (new BoxLayout (c, BoxLayout.PAGE_AXIS)); // impila gli elementi in verticale p = new JPanel(); l = new JLabel ("Digita il tuo nome"); t = new JTextField(nome, 10); t.setforeground(color.red); // testo rosso t.setbackground(color.lightgray); // sfondo grigio chiaro per la casella di testo t.addactionlistener(this); disegno = new MioPanel(t); p.add(l); p.add(t); c.add(p); c.add(disegno); f.setsize(200,200); // con fpack bisogna ingrandire la finestra per vedere il "disegno" f.setlocation(0,0); // se non se ne impostano le dimensioni f.setresizable(true); f.setvisible(true);
37 f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); // deve essere posta prima del ciclo di disegno while(true) disegno.go(); // senza craere thread public void cancellanome() { t.settext(""); public void actionperformed(actionevent e) { cancellanome(); // alla pressione di INVIO public static void main(string [] args) { new SenzaThread(); // classe esterna class MioPanel extends JPanel { private String nome; private JTextField testo; private int Xpos; public MioPanel (JTextField t) { testo = t; public void go () { // servizio richiesto for (Xpos =0; Xpos<getWidth(); Xpos++) { // ascissa massima // in funzione della larghezza del pannello setforeground(color.black); // scrive in nero repaint(); try{ Thread.sleep(80); catch(interruptedexception ie) {return; public void paintcomponent(graphics g) { super.paintcomponent(g); nome = testo.gettext(); g.drawstring("ciao " + nome, Xpos,50); // scelta dell'ordinata in modo da vedere meglio la scritta
38 Esempio d'uso JComboBox, eventi di azione, più pannelli e threads import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Pannelli implements ActionListener { private JLabel l; private JComboBox cbx; private String[] nome = {"produttore", "consumatore"; private JTextField t; private MioPanel disegno; private JPanel p1, p2; private JFrame f ; private Container c; public Pannelli() { // costruttore f = new JFrame ("Uso threads"); c = f.getcontentpane(); //c.setlayout (new BoxLayout (c, BoxLayout.PAGE_AXIS)); // impila gli elementi in verticale in c c.setlayout(new GridLayout(3,1)); // unica colonna con stesso effetto p1 = new JPanel(); p2 = new JPanel(); l = new JLabel ("Scegli"); cbx = new JComboBox(); for (int k = 0; k < nome.length; k++) cbx.additem (nome[k]); cbx.seteditable (false); cbx.addactionlistener (this); cbx.setforeground(color.red); // testo rosso cbx.setbackground(color.lightgray); // sfondo grigio chiaro per combobox cbx.settooltiptext("seleziona una voce"); t = new JTextField (nome[0],7); t.seteditable (false); disegno = new MioPanel(t); p1.add(l); p1.add(cbx); p2.add(t); p2.setbackground(color.yellow); // per evidenziare le dimensioni del secondo pannello c.add(p1); c.add(p2); c.add(disegno); f.setsize(200,200); // con fpack bisogna ingrandire la finestra per vedere "disegno" f.setlocation(300, 100); // se non se ne impostano le dimensioni f.setresizable(false); f.setvisible(true); Thread runner = new Thread (disegno); runner.start(); // richiama il metodo run() del thread disegno f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public void actionperformed(actionevent e) { t.settext ("" +((JComboBox) e.getsource()).getselecteditem()); // alla pressione di INVIO public static void main(string [] args) { new Pannelli();
39 // classe esterna class MioPanel extends JPanel implements Runnable{ private String nome; private JTextField testo; private int Xpos; public MioPanel (JTextField t) { testo = t; setforeground(color.black); // scrive in nero public void run () { // metodo obbligatorio per eseguire thread while (true) { for (Xpos =0; Xpos<getWidth(); Xpos++) { // ascissa massima // in funzione della larghezza del pannello repaint(); try{ Thread.sleep(80); catch(interruptedexception ie) {return; public void paintcomponent(graphics g) { super.paintcomponent(g); int raggio = 50; nome = testo.gettext(); g.setcolor(color.blue); g.drawstring(nome, Xpos,50); if (nome.equals ("produttore")){ g.setcolor(color.red); g.filloval(xpos,5,raggio/2,raggio/2); // x,y dell'angolo in alto a sinistra, // larghezza, altezza
40 JTextField e documento: eventi swing Associato ad ogni campo di testo c è un documento che gestisce il testo presente e ad ogni modifica del contenuto questo documento genera un DocumentEvent per segnalare l'avvenuto cambiamento.tale evento dev'essere gestito da un opportuno DocumentListener L'interfaccia DocumentListener dichiara tre metodi: void insertupdate(documentevent e); void removeupdate(documentevent e); void changedupdate(documentevent e); Il terzo non è mai chiamato da un JtextField, serve solo per altri tipi di componenti L'oggetto DocumentEvent passato come parametro non ha nessuna utilità nel nostro esempio. Nel nostro caso l'azione da svolgere in caso di inserimento o rimozione di caratteri è identica, quindi i due metodi void insertupdate(documentevent e); void removeupdate(documentevent e); saranno identici (purtroppo vanno comunque implementati entrambi) Anche metodo il changedupdate(documentevent e) è inutile, dato che JTextField non lo chiama ma va comunque formalmente implementato. import javax.swing.event.*; import java.awt.*; import javax.swing.*; class Es12Panel extends JPanel implements DocumentListener{ JTextField txt1, txt2; public Es12Panel(){ super(); txt1 = new JTextField("Scrivere qui il testo", 25); txt2 = new JTextField(25); txt2.seteditable(false); txt1.getdocument().adddocumentlistener(this); // ricava il documento di cui il campo di testo txt1 fa parte, e gli // associa come listener il pannello add(txt1); add(txt2); public void insertupdate(documentevent e){ txt2.settext(txt1.gettext()); public void removeupdate(documentevent e){ txt2.settext(txt1.gettext()); public void changedupdate(documentevent e){ public class DocumentP{ public static void main(string [] args){ JFrame f = new JFrame ("Testo"); Container c = f.getcontentpane(); Es12Panel guip = new Es12Panel(); guip.setbackground(color. lightgray); // sfondo del pannello colorato c.add(guip); // aggiunge il pannello f.setsize(300,100); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE);
41 ADT JList (da Tutorial Sun) import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class ListDemo extends JPanel implements ListSelectionListener { private JList list; private DefaultListModel listmodel; // in javax.swing private static final String hirestring = "Hire"; private static final String firestring = "Fire"; private JButton firebutton; private JTextField employeename; public ListDemo() { super(new BorderLayout()); listmodel = new DefaultListModel(); listmodel.addelement("debbie Scott"); listmodel.addelement("scott Hommel"); listmodel.addelement("sharon Zakhour"); //Create the list and put it in a scroll pane. list = new JList(listModel); list.setselectionmode(listselectionmodel.single_selection); list.setselectedindex(0); list.addlistselectionlistener(this); list.setvisiblerowcount(5); JScrollPane listscrollpane = new JScrollPane(list); JButton hirebutton = new JButton(hireString); HireListener hirelistener = new HireListener(hireButton); hirebutton.setactioncommand(hirestring); hirebutton.addactionlistener(hirelistener); hirebutton.setenabled(false); firebutton = new JButton(fireString); firebutton.setactioncommand(firestring); firebutton.addactionlistener(new FireListener()); employeename = new JTextField(10); employeename.addactionlistener(hirelistener); employeename.getdocument().adddocumentlistener(hirelistener); String name = listmodel.getelementat( list.getselectedindex()).tostring(); //Create a panel that uses BoxLayout. JPanel buttonpane = new JPanel(); buttonpane.setlayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); buttonpane.add(firebutton); buttonpane.add(box.createhorizontalstrut(5)); buttonpane.add(new JSeparator(SwingConstants.VERTICAL)); buttonpane.add(box.createhorizontalstrut(5)); buttonpane.add(employeename); buttonpane.add(hirebutton); buttonpane.setborder(borderfactory.createemptyborder(5,5,5,5)); add(listscrollpane, BorderLayout.CENTER); add(buttonpane, BorderLayout.PAGE_END);
42 class FireListener implements ActionListener { public void actionperformed(actionevent e) { //This method can be called only if there's a valid selection //so go ahead and remove whatever's selected. int index = list.getselectedindex(); listmodel.remove(index); int size = listmodel.getsize(); if (size == 0) { firebutton.setenabled(false); //Nobody's left, disable firing. else { if (index == listmodel.getsize()) { //Select an index. //removed item in last position index--; list.setselectedindex(index); list.ensureindexisvisible(index); //This listener is shared by the text field and the hire button. class HireListener implements ActionListener, DocumentListener { private boolean alreadyenabled = false; private JButton button; public HireListener(JButton button) { this.button = button; //Required by ActionListener public void actionperformed(actionevent e) { String name = employeename.gettext(); //User didn't type in a unique name... if (name.equals("") alreadyinlist(name)) { Toolkit.getDefaultToolkit().beep(); employeename.requestfocusinwindow(); employeename.selectall(); return; int index = list.getselectedindex(); //get selected index if (index == -1) { //no selection, so insert at beginning index = 0; else { //add after the selected item index++; listmodel.insertelementat(employeename.gettext(), index); //If we just wanted to add to the end, we'd do this: //listmodel.addelement(employeename.gettext()); //Reset the text field. employeename.requestfocusinwindow(); employeename.settext(""); //Select the new item and make it visible. list.setselectedindex(index); list.ensureindexisvisible(index);
43 //This method tests for string equality. You could certainly //get more sophisticated about the algorithm. For example, //you might want to ignore white space and capitalization. protected boolean alreadyinlist(string name) { return listmodel.contains(name); //Required by DocumentListener public void insertupdate(documentevent e) { enablebutton(); //Required by DocumentListener. public void removeupdate(documentevent e) { handleemptytextfield(e); //Required by DocumentListener. public void changedupdate(documentevent e) { if (!handleemptytextfield(e)) { enablebutton(); private void enablebutton() { if (!alreadyenabled) { button.setenabled(true); private boolean handleemptytextfield(documentevent e) { if (e.getdocument().getlength() <= 0) { button.setenabled(false); alreadyenabled = false; return true; return false; //This method is required by ListSelectionListener. public void valuechanged(listselectionevent e) { if (e.getvalueisadjusting() == false) { if (list.getselectedindex() == -1) { //No selection, disable fire button. firebutton.setenabled(false); else { //Selection, enable the fire button. firebutton.setenabled(true);
44 /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createandshowgui() { //Create and set up the window. JFrame frame = new JFrame("ListDemo"); frame.setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newcontentpane = new ListDemo(); newcontentpane.setopaque(true); //content panes must be opaque frame.setcontentpane(newcontentpane); //Display the window. frame.pack(); frame.setvisible(true); public static void main(string[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.swingutilities.invokelater(new Runnable() { public void run() { createandshowgui(); ); Inserimento: automaticamente ordinato Cancellazione della voce selezionata: prima dopo.
45 Esercizio: Disegno di un auto in altra finestra alla pressione di un pulsante (evento della GUI) Con codice HTML: <html> <head> <title>disegno di un Auto come evento </title> </head> <body> <object code ="Autoe.class" width = "350" height ="70" > </object> </body> </html> // Applet Autoe.java // esempio di Applet con gestione eventi della GUI: creazione di eventi personalizzati // Uso canvas import java.applet.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Autoe extends JApplet { Auto A; public void init() { JButton B = new JButton ("Disegna un auto"); GestiscePulsante A1 = new GestiscePulsante(); // crea ascoltatore B.addActionListener (A1); // lega la classe di ascolto all origine dell evento: cioè // il pulsante B add(b); public void Disegna() { JFrame f1 = new JFrame("Disegna auto"); A = new Auto(); f1.setsize (300, 200); f1.setlocation (50,50); f1.setresizable(true); // con mouse ridimensionabile Container c = f1.getcontentpane(); // recupera il "muro grezzo" c.add(a); f1.setvisible(true);
46 // definizione classe d'ascolto interna cioè innestata non statica private class GestiscePulsante implements ActionListener{ // interfaccia per eventi di azione public void actionperformed (ActionEvent e) { // unico metodo da ridefinire Disegna(); // fine classe d'ascolto class Auto extends Canvas { // classe esterna per disegnare auto public void paint(graphics g) { Font f = new Font("Times Roman", Font.BOLD, 20); // tipo, aspetto, dimensione carattere g.setfont(f); g.filloval(120, 220, 60,60); // una ruota piena g.filloval(320, 220, 60,60); // altra ruota piena g.setcolor(color.blue); // carrozzeria blu g.drawrect(50, 150, 400, 70); g.drawline(170,150,200,100); g.drawline(330,150,300,100); g.drawline(300,100,200,100); g.setcolor(color.yellow); // luci gialle g.fillrect(50, 170, 20, 30); g.setcolor(color.red); // luci rosse g.fillrect(430, 150, 20, 20); g.setcolor(color.cyan); // testo cyan g.drawstring("automobile", 200, 350); Classi innestate e interne: definizione Una classe innestata non è altro che una classe che viene definita all interno di un altra classe. Il vantaggio di implementare una classe all interno di un altra, riguarda principalmente il risparmio di codice. Infatti, la classe innestata ha accesso alle variabili di istanza della classe in cui è innestata. N.B. : se compiliamo una classe che contiene una classe innestata, saranno creati due file: "nomeclasseesterna.class" e "nomeclasseesterna$nomeclasseinnestata.class". N.B. : fino alla versione 1.3 di Java, il termine classe innestata non era stato ancora adottato. Si parlava invece di classe interna ( inner class ). Dalla versione 1.4 in poi, la Sun ha deciso di sostituire il termine classe interna, con il termine classe innestata o classe annidata ( nested class ). Il termine classe interna deve ora essere utilizzato solo per le classi innestate che non sono dichiarate statiche. In realtà la stragrande maggior parte delle volte si utilizzano classi interne.
47 Leggere testo di input con applicazioni GUI e il package swing Esempio di Applet che usa una semplice finestra modale: // da eseguire con appletviewer da linea di comando > appletviewer Finestre.html // oppure con opportune selezioni nel Plug-in (da Pannello di controllo) // oppure in ambiente JCreator import javax.swing.*; import java.awt.*; import java.applet.*; public class Finestre extends JApplet { String nome=""; public void init () { nome = JOptionPane.showInputDialog("Inserisci il tuo nome: "); public void paint(graphics g) { g.drawstring("ciao " + nome, 10, 50); Con codice HTML (file Finestre.html ): <html> <head> <title>dialog box per input </title> </head> <body> <object code ="Finestre.class" width = "300" height = "100"> </object> </body> </html> nb: per eseguire la pagina html con programma appletviewer, inserito come tools in JCreator, impostare come opzioni: Per scoprire le potenzialità di swing5 eseguire la demo in file compresso seguendo percorso C:\Programmi\Java\jdk1.6.0_21\demo\jfc\SwingSet2\SwingSet2.jar o lanciare Launch SwingSet3 (richiede Java 6) 5 SWING
48 Esempio senza apparente gestione di eventi import javax.swing.*; import java.awt.*; import java.awt.event.*; public class AppIcone extends JFrame { private JButton btnicone; private JLabel testo; private Icon[] figure = { new ImageIcon ("../src/img/inverno.gif"), new ImageIcon ("../src/img/estate.gif"), new ImageIcon ("../src/img/ninfee.gif") ; // percorso relativo alla sottocartella classes in cui è memorizzato il bytecode // se nella stessa cartella./nomeimage public AppIcone () { Container cnt = getcontentpane(); // di default con gestore di layout tipo BorderLayout btnicone = new JButton (figure[1]); // immagine se il mouse è al di fuori della finestra // di default setrolloverenabled (true) // abilitazione del riconoscimento del trascinamento del mouse (roll over) btnicone.setrollovericon (figure[0]); // definizione dell icona da usare durante lo scorrimento del mouse btnicone.setpressedicon (figure[2]); // definizione dell icona da usare a seguito di click sul mouse btnicone.settooltiptext ("Spendido inverno! Premi per vedere ninfee! "); cnt.add (btnicone, BorderLayout.CENTER); testo = new JLabel("Effetto Roll-Over"); cnt.add (testo, BorderLayout.PAGE_END); pack(); setvisible (true); setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string args []){ AppIcone o = new AppIcone(); nb: salvando in stessa cartella il sorgente e la sottocartella che contiene le immagini IMG
49 Uso componente JColorChooser per visualizzare in finestra modale palette di colori import javax.swing.*; import java.awt.*; // per Color class SceltaColore extends JFrame { public void visualizza(){ JColorChooser c = new JColorChooser(); c.showdialog(this,"palette", Color.white); // visualizza finestra modale pack(); setvisible(true); setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main (String arg[]){ SceltaColore o = new SceltaColore(); o.visualizza(); // fine main // fine classe JFileChooser per visualizzare finestre modali per aprire e salvare file class ScelteFile extends JFrame { public void visualizza(){ JFileChooser fc = new JFileChooser(); fc.showopendialog(this); // apre finestra modale... visualizza un JFileChooser per apertura file. fc.showsavedialog(null); // apre finestra modale... visualizza un JFileChooser per salvataggio file. pack(); setvisible(true); setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main (String arg[]){ ScelteFile o = new ScelteFile0(); o.visualizza(); // fine main // fine classe
50 APPENDICE: APPLET Java si è diffuso storicamente, e trae forza, dal concetto di applet6 come piccola (almeno all inizio dei tempi) applicazione da eseguirsi dentro un browser Internet grafica portabile ed eseguibile ovunque modello di sicurezza sandbox Una applet ("applicazioncina") è una applicazione non autonoma, ma pensata per far parte di una pagina Internet porta dinamicità alle pagine HTML "statiche" viene eseguita dal browser, che quindi deve incorporare un interprete Java e questo può causare un tempo di visualizzazione più alto In quanto applicazione non autonoma, un'applet: non ha un main, perché la sua vita è dipendente dalla pagina in cui è visualizzata, eredita dalla superclasse ed è public. non deve creare un frame principale, perché usa la finestra del browser che la ospita (in effetti, Applet deriva direttamente da Panel e quindi è essa stessa un pannello) è organizzata intorno a 4 metodi standard: init(), che gioca il ruolo del costruttore start() e stop(), chiamati dal browser ogni volta che occorre avviare /fermare l'applet destroy(), invocato quando il browser viene chiuso. Diagramma degli stati di un applet Esistono due versioni di Applet: la classe Applet dell'awt standard (da Java 1.0 in poi) la classe JApplet di Swing (da Java in poi) Se si usano componenti Swing, occorre necessariamente usare JApplet infatti una Applet con componenti Swing non viene disegnata correttamente 6 Da
51 // AppletSaluto.java import java.awt.graphics; // importa solo la necessaria classe Graphics definita all interno del package // che implementa l Interfaccia Utente detta Abstract Windowing Toolkit public class AppletSaluto extends java.applet.applet { // AppletSaluto è sottoclasse di Applet public void paint(graphics g) { g.drawstring("ciao alla citta!", 5, 25); // coordinate dell angolo in basso // a sinistra del testo Con file HTML che fa riferimento al file bytecode dell applet: <object code="appletsaluto.class" width="195"height="38"> </object> Si ottiene il seguente effetto con uso di BROWSER (Internet Explorer recenti o FireFox Mozilla) Ciao alla citta '! cioè una scritta nella finestra del browser (5, 25) // SecondoApplet.java con passaggio di parametri import java.awt.*; import java.applet.*; public class SecondoApplet extends Applet { public void paint(graphics g) { String nome = getparameter ("Nome"); g.drawstring("ciao " + nome, 0, 50); Con file HTML <html> <head><title> Saluto personalizzato</title></head> <body> <object code="secondoapplet.class" width="195"height="38"> <param name="nome" value="nome_proprio"> </object> </body> </html> Si ottiene il seguente effetto con uso di BROWSER (Internet Explorer): Ciao Nome_proprio cioè un saluto personalizzato nella finestra del browser
52 // esempio di applet con descrizione degli Stati (ridefinizione di metodi originali) // da lanciare con appletviewer da linea di comando > appletviewer Stati.html oppure da browser7 // Notare l assenza del metodo main() infatti definiamo Stati come sottoclasse di Applet che viene // usata dalla classe principale predefinita AppletViewer al momento dell esecuzione // oppure dalla JVM integrata nel browser import java.applet.*; public class Stati extends Applet { public Stati () { // Stati è sottoclasse di Applet con costruttore Applet() // costruttore System.out.println("Invocato il costruttore di stati"); public void init () { // richiamato unica volta: quando carica l'applet // cioè quando il browser lo preleva dal Web Server super.init(); // metodo originale System.out.println("Eseguito init()"); public void start () { // richiamato ogni volta che si accede a pagina web // invoca metodo paint(..) super.start(); // metodo originale System.out.println("Eseguito start()"); public void stop () { // richiamato ogni volta che si esce da pagina web // sia finestra iconizzata, sia non in primo piano super.stop(); // metodo originale System.out.println("Eseguito stop()"); public void destroy () { // richiamato quando si esce dall'appletviewer o da browser super.destroy(); // metodo originale System.out.println("Eseguito destroy()"); Codice HTML salvato nel file Stati.html: <html> <head><title>stati di un Applet </title></head> <body>lancia con appletviewer da linea di comando <P> > appletviewer Stati.html <P><object code ="Stati.class" width = 10 height = 10 ></object> <br>oppure seleziona da barra delle applicazioni: <em> Apri console</em> </body> </html> 7 Lanciando da browser aprire visualizzazione console (simbolo Plug-in Java che compare nella barra di sistema) NB: da pannello di controllo (Java Plug-in) si deve scegliere l opzione Mostra Java nella barra di sistema e selezionare i browser in cui usare Java Plug-in come runtime Java predefinito
53 APPLET e SICUREZZA Un'applet non può fare tutto quello che fa una applicazione. Poiché può essere scaricata dalla rete, sarebbe troppo pericoloso permettere a un'applet di fare qualunque cosa ed è costretta a rispettare un ben preciso modello di sicurezza ("sandbox") è eseguita in una "scatola" da cui non può uscire non può contaminare (o spiare) i dati del computer dell'utente Un'applet di norma non può: accedere al file system locale (neppure per leggere un file) eseguire un altro programma ottenere informazioni sull'utente connettersi via rete a un computer diverso da quello da cui è stata scaricata8 caricare la libreria Java, chiamare System.exit() In molte situazioni, questi vincoli sono troppo rigidi e rischierebbero di rendere impossibile la costruzioni di applet utili. APPLET FIRMATE Attraverso tecnologie di cifratura, un'applet può essere firmata, ossia a essa può essere allegato un certificato che ne garantisce l'origine. A tali applet firmate, cui si attribuisce maggiore fiducia, l'utente può consentire di svolgere alcune o tutte le operazioni sottoposte a vincolo. Ogni browser può essere configurato per gestire le applet firmate. POLITICHE DI SICUREZZA A partire da Java 2, l'utente può decidere caso per caso quali politiche di sicurezza applicare, con una granularità molto fine Esiste il concetto di policy file, che elenca le politiche locali e si può stabilire che una certa applet, proveniente da un ben preciso sito, ha diritti particolari. Un tale file può essere fornito da chi sviluppa l'applet, o modificato dall'utente con lo strumento PolicyTool. 8 Per questo motivo si preferisce lavorare con applicazioni quando ci si connette a Internet e se ne usano le risorse.
54 Graphics Un oggetto di tipo Graphics rappresenta essenzialmente una porzione di schermo in cui è possibile mostrare testi, immagini, forme, in modo indipendente dalla piattaforma Per disegnare su un oggetto GUI (di tipo contenitore), dobbiamo chiamare opportuni metodi sull oggetto Graphics dello stesso. Esistono due modi: ottenere l oggetto Graphics con oggettogui.getgraphics() modificare il metodo di disegno del contenitore cioè estendere la classe ereditando da una classe Frame o Container o Panel (package awt) o JPanel (swing) Non solo l'applet ha il metodo paint che può essere ridefinito, ma anche gli oggetti di tipo Component, ovvero tutti i componenti GUI (del package awt)9, quindi per cambiare l'aspetto grafico di un qualsiasi componente grafico basta ridefinirne10 il metodo paint. Tra tutti i Component c'è la tela su cui è possibile disegnare, essa è un oggetto della classe Canvas. Chi è abituato a programmare con altri linguaggi si aspetterà che nel metodo paint ci sia un inizializzazione del device su cui si va a disegnare e poi una serie di istruzioni tipo drawline, drawbox eccetera [ 1], ma questo non è del tutto vero, ovvero nei Component e nelle applet non c'è nessun metodo grafico. Il parametro g di tipo Graphics del metodo paint o paintcomponent, infatti, contiene i metodi grafici usabili da Java e rappresenta in qualche modo l'area (contesto grafico) in cui verranno disegnate le varie primitive. I metodi paint (Graphics g) e paintcomponent(graphics g) non possono essere invocati direttamente. Per disegnare un oggetto di tipo Graphics utilizzando ad esempio il metodo paint( ) della classe Component, passando come parametro il contesto grafico di tipo Graphics, si crea una classe che estende il Frame dentro il quale si vuole disegnare: import java.awt.frame; import java.awt.graphics; public class SimpleGrafica extends Frame { public void paint (Graphics g) { g.drawrect(10, 10, 100, 75); // x, y, larghezza, altezza Graphics è una classe che non può essere istanziata: nel metodo paint o paintcomponent viene ricevuto un oggetto di tale classe come parametro e se ne possono usare i metodi oppure si può recuperare il contesto grafico (di un contenitore: di tipo Frame o Container o Panel in awt o JPanel in swing) che possiede tutti i metodi di disegno. Per ottenere il contesto grafico ad esempio della finestra corrente usando il metodo getgraphics( ): Graphics g = getgraphics(); nb: usando il metodo getgraphics() sarà necessario richiamare il metodo dispose() per deallocare l oggetto quando se ne termina l uso. [1] nel disegnare in ambiente Dev-Cpp: int GraphDriver = DETECT, GraphMode; // rileva la più alta risoluzione possible tipicamente // VGA (640 x 480) ed equivale a GraphDriver=0 // auto-detected cioè GraphMode=0 tipicamente VGAHI int Xpixel= 640, Ypixel=480; initgraph (&GraphDriver, &GraphMode, "", Xpixel, Ypixel); setcolor(cyan); 9 10 // Start Window con inizializzazione device // funzione per settare il colore impostato per gli assi Analogamente per gli oggetti di tipo JComponent (swing) esiste il metodo paintcomponent
55 GRAFICA BI-DIMENSIONALE IN JAVA Esempio Pannello con grafica personalizzato: ExDraw1.java. La funzione paintcomponent riempe un rettangolo sfumato, vi disegna dentro un fumetto con scritto grande "Ciao!", traccia con tratto spesso tre linee alla base del fumetto. Disegno diretto Metodi per disegnare direttamente una figura. I parametri sono interi esprimenti numero di pixel, cioè le primitive vanno fornite direttamente in device space. clearrect(x,y, width,height): pulisce il rettangolo indicato riempiendolo col colore di sfondo. void draw/fillrect(x,y, width,height): Disegna rettangolo vuoto o pieno. void draw/fillroundrect(x,y, width,height, arcwidth,archeight): Disegna rettangolo con angoli smussati, vuoto o pieno. void draw/fill3drect(x,y, width,height, arcwidth,archeight): Disegna rettangolo con effetto di rilievo 3D, vuoto o pieno. draw/filloval(x,y, width,height): Disegna ellisse, vuoto o pieno. draw/fillarc(x,y, width,height, startangle,arcangle): Disegna arco circolare o ellittico, vuoto o pieno. Gli angoli sono in gradi, angolo positivo significa rotazione in senso antiorario, negativo in senso orario. Centro dell'arco e' il centro del rettangolo di origine (x,y) e dimensioni width, height. drawline(x1,y1, x2,y2): Disegna segmento di retta tra (x1,y1) e (x2,y2). draw/fillpolygon(arrayx, arrayy, n): Disegna poligono con n vertici definiti dai due array di x e y. drawpolyline(arrayx, arrayy, n): Disegna spezzata poligonale con n vertici definiti dai due array di x e y. drawstring(stringa,x,y): Disegna stringa iniziando alle coordinate (x,y). La stringa si estende a destra di x e sopra y, cioe' nelle ascisse maggiori di x e nelle ordinate MINORI di y. drawimage(image, x,y, ImageObserver): Disegna immagine alla posizione (x,y). Come image observer si passa il componente stesso (this). drawimage(image, x,y, width,height, ImageObserver): disegna immagine alla posizione (x,y), scalata alla larghezza ed altezza indicate. Esempio per disegnare immagine che occupa tutta la componente: Dimension d = getsize(); g.drawimage (image, 0,0, d.width,d.height, this); Tutorial Sun
56 APPENDICE: Gestione semplificata delle immagini Le immagini memorizzate in file locali o su Internet possono essere lette in un'applicazione Java e visualizzate da oggetti Graphics. A partire dal JDK 1.4 la lettura di un'immagine è molto semplice e non richiede il recupero del "toolkit di default" nè la creazione di un oggetto di tipo MediaTracker per tracciare le immagini nel componente assegnato né l'attesa se più di un'immagine deve essere caricata prima di poterla disegnare. Se l'immagine è memorizzata in un file locale si possono usare le seguenti linee di codice: String filename= nome del file comprensivo del percorso Image image = ImageIO.read(new File(filename)); In alternativa è possibile indicare un URL: String urlname= protocollo completo con nome risorsa Image image = ImageIO.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 ad un oggetto che incapsula i dati dell'immagine. È possibile visualizzare l'immagine col metodo drawimage della classe Graphics. // Disegnare immagini su un pannello import import import import import java.awt.*; java.awt.image.*; java.io.*; javax.imageio.imageio; javax.swing.*; public class ImmaginePannello extends JPanel{ private BufferedImage image; // con atenzione alla bufferizzazione public ImmaginePannello() { try { image = ImageIO.read(new File("immagini/verde.gif")); // cartella immagini in sottocartella con bytecode catch (IOException e) {// handle exception. public void paintcomponent(graphics g) { g.drawimage(image, 0, 0, null); public static void main(string [] args){ JFrame f = new JFrame("Visualizzazione Immagini"); ImmaginePannello p = new ImmaginePannello(); f.setcontentpane(p); f.setsize(300,210); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE);
57 // Disegnare su un pannello immagini recuperate da Internet import import import import import import java.awt.*; java.awt.image.*; java.io.*; java.net.url; javax.imageio.imageio; javax.swing.*; public class ImmagineURL extends JPanel{ private BufferedImage image; public ImmagineURL() { try { image = ImageIO.read(new URL (" catch (IOException ex) { // handle exception public void paintcomponent(graphics g) { g.drawimage(image, 0, 0, null); public static void main(string [] args){ JFrame f = new JFrame("Visualizzazione Immagini"); ImmagineURL p = new ImmagineURL(); f.setcontentpane(p); f.setsize(300,250); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE);
58 Una galleria di immagini con Java /** * * Immagini application * una galleria di immagini con recupero di URL * quarte /4/9 */ import java.awt.*; import java.awt.event.*; import javax.swing.*; /* * la mini gallery necessita di alcune immagini * salvate nell'omonima cartella con lo stesso percorso dei file.class * immagini/rosso.gif * immagini/blu.gif * immagini/verde.gif * immagini/rosa.gif * immagini/giallo.gif * immagini/azzurro.gif * immagini/viola.gif */ public class Immagini extends JPanel implements ActionListener { //definiamone attributi e metodi JLabel pic; public Immagini() { super(new BorderLayout()); // per rendere possibili allineamenti [*] //definiamo i nomi da associare alle immagini String[] colopics = { "Rosso", "Blu", "Verde", "Rosa", "Giallo", "Azzurro", "Viola" ; //creiamo la lista delle immagini // si seleziona l'ultima voce JComboBox cololist = new JcomboBox(coloPics); cololist.setselectedindex(6); cololist.addactionlistener(this); //definiamo le informazioni relative alle immagini pic = new JLabel(); pic.setfont(pic.getfont().derivefont(font.bold)); pic.sethorizontalalignment(jlabel.left); // allineamento [*] updatelabel(colopics[cololist.getselectedindex()]); pic.setborder(borderfactory.createemptyborder(5,0,0,0)); //impostiamo la dimensione delle immagini pic.setpreferredsize(new Dimension(200, )); //settiamo i bordi e i colori. add(cololist, BorderLayout.PAGE_START); add(pic, BorderLayout.PAGE_END);
59 setborder(borderfactory.createemptyborder(15,15,15,15)); // gestione eventi di azione public void actionperformed(actionevent e) { JComboBox cb = (JComboBox)e.getSource(); String nomepic = (String)cb.getSelectedItem(); updatelabel(nomepic); // recupero immagine con controllo esistenza file // apertura e lettura del contenuto della cartella protected void updatelabel(string name) { ImageIcon icon = createimageicon("immagini/" + name + ".gif"); pic.seticon(icon); pic.settooltiptext("colore: " + name.tolowercase()); if (icon!= null) { pic.settext(null); else{ pic.settext("impossibile trovare la pagina"); //notifica nel caso l'immagine non sia nel percorso specificato protected static ImageIcon createimageicon(string path) { java.net.url imgurl = Immagini.class.getResource(path); //nomeapplicazione..class.getresource(path)per recuperare l'url cioè il percorso del file if (imgurl!= null) { return new ImageIcon(imgURL); else{ System.err.println("Impossibile trovare il file: " + path); return null; //creazione dell'interfaccia private static void InterfacciaGrafica() { //setaggio della finestra JFrame frame = new JFrame("MiniGallery"); frame.setdefaultcloseoperation(jframe.exit_on_close); JComponent newcontentpane = new Immagini(); newcontentpane.setopaque(true); frame.setcontentpane(newcontentpane); //mostriamo la finestra che contiene la GUI frame.pack(); frame.setvisible(true); public static void main(string[] args) { // creaiamo il visualizzatore e mostriamo la GUI javax.swing.swingutilities.invokelater(new Runnable() { public void run() { InterfacciaGrafica();); // fine applicazione // in realtà sarebbe sufficiente mostrare la GUI senza creare oggetto runnable
60 Inserire immagini o disegnare con ImageIcon è usata per piccole immagini su bottoni o etichette e per disegnare su qualunque componente di tipo JComponent. La classe javax.swing.imageicon Risulta molto semplice inserire un'immagine di tipo ImageIcon in un bottone o etichetta: ad esempio per inserirla in un componente di tipo JLabel basta il seguente codice: ImageIcon icon = new ImageIcon("nome del file comprensivo del percorso"); JLabel label = new JLabel(icon); // Inserire immagini di tipo ImageIcon in un componente di tipo JLabel import java.awt.*; import javax.swing.*; public class ImageLabel{ private private private private ImageIcon icon; JFrame f; JLabel label; JPanel p; public ImageLabel() { icon = new ImageIcon("immagini/verde.gif"); // immagine caricata da file in cartella immagini // nella stessa sottocartella del bytecode f = new JFrame("Visualizzazione Immagine"); label = new JLabel(icon); p = new JPanel(); p.add(label); f.setcontentpane(p); f.setsize(300,210); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string [] args){ new ImageLabel (); nb: si può caricare, come per tutte le immagini, da URL String url=" java.net.url where = new URL(url); ImageIcon anothericon = new ImageIcon(where);
61 Per disegnare su un componente di tipo JComponent si ricorre al metodo painticon con la seguente sintassi: nomeimageicon.painticon(component c, Graphics g, int x, int y); Altri metodi utili: int w = nomeimageicon.geticonwidth(); int h = nomeimageicon.geticonheight(); // Disegnare immagini di tipo ImageIcon in un componente di tipo JLabel (che è di tipo JComponent) import java.awt.*; import javax.swing.*; public class ImageIconLabel{ private JFrame f; private MyIcon disegno; public ImageIconLabel() { f = new JFrame("Visualizzazione Immagine"); disegno = new MyIcon(); f.setcontentpane(disegno); // l'etichetta personalizzata è inserita sul muro grezzo f.setsize(300,210); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main(string [] args){ new ImageIconLabel(); // fine applicazione //classe esterna class MyIcon extends JLabel{ //oppure, più generico, estendendo dalla classe JComponent private ImageIcon icon; public MyIcon(){ icon = new ImageIcon("immagini/verde.gif"); // cartella immagini in sottocartella con bytecode public void paintcomponent(graphics g) { super.paintcomponent(g); icon.painticon(this, g, 5, 5); // disegno posizionato rispetto alla cornice x = 5 pixel y = 5 pixel
62 APPENDICE: Introduzione agli eventi e loro gestione Un evento è un messaggio che il sistema genera in risposta a un azione effettuata generalmente dall utente quando interagisce con l applicazione. Gli eventi vengono gestiti dal sistema, che effettua per prima cosa alcune operazioni predefinite, e quindi passa il controllo a una procedura, detta procedura-evento, con la quale il programmatore specifica il comportamento dell applicazione in risposta all evento. Si parla di modello a delega quando il programmatore può decidere a quale ascoltatore delegare la gestione dell evento. Gli eventi più comuni sono quelli generati dal mouse o dalla tastiera. Le procedure-evento Una procedura-evento è una procedura specificamente associata a un dato oggetto e a un dato evento che può interessare quell oggetto. Le procedure-evento servono al programmatore per specificare il comportamento dell applicazione in risposta al verificarsi di un dato evento su un certo oggetto. Ambienti visuali: oggetti predefiniti Gli oggetti predefiniti sono gli elementi di base di applicazioni visuali. Al contrario degli ambienti OOP puri, nei quali il programmatore definisce gli oggetti come blocchi di codice e di dati correlati, negli ambienti visuali gli oggetti sono entità preconfezionate, già pronte per l uso. Queste entità sono elementi reali, come caselle di testo o pulsanti di comando. L ambiente di sviluppo mette a disposizione apposite barre di pulsanti che servono per la creazione degli oggetti. Ogni pulsante sulla barra rappresenta un tipo di oggetto predefinito disponibile. Lo sviluppatore seleziona il pulsante corrispondente al tipo di oggetto che vuole creare e quindi lo traccia su una finestra. Successivamente ne imposta le proprietà e infine scrive le procedure-evento necessarie per far rispondere l oggetto alle azioni dell utente. Schede di approfondimento Ambienti visuali ed eventi da con approfondimento in
63 Eventi e linguaggio Java: modello a delega Nel linguaggio Java, quando l utente di una interfaccia grafica (GUI) digita caratteri o usa il mouse o un componente dell interfaccia grafica, il gestore delle finestre di Java invia una comunicazione al programma per segnalare che si è verificato un evento. Oggetto GUI Genera evento Oggetto ascoltatore Classe che implementa event listener Risposta a evento Interfaccia: metodi per rispondere a evento Esistono classi d ascolto di eventi (event listener) per permettere ad un programma di indicare quali eventi gradisce ricevere. Ogni programma dovrà creare un oggetto per ognuna delle classi cui è interessato; tali oggetti prendono il nome di ascoltatori (oggetto di una classe di ascolto). La classe di ascolto deve implementare almeno una interfaccia di ascolto (interfacce di tipo listener). Un ascoltatore di eventi è un oggetto di una classe di ascolto che implementa almeno una interfaccia di ascolto. Tali interfacce11 sono segmenti software predefiniti per gestire l evento. Per creare un ascoltatore bisogna conoscere l origine dell evento che può essere ad esempio l intera Applicazione o Applet (programma Java eseguibile da browser) o una sua parte. Per origine dell evento si intende il contenitore o il componente che può generare l evento (ad esempio un pulsante è l origine dell evento di azione tipo clic su pulsante ). 11 Contenute nel package java.awt.event libreria che deve essere importata.
64 I passi, dunque, per gestire gli eventi programmando in Java sono i seguenti: 1. Decidere quali eventi interessano l applicazione o l applet. Tale fase si traduce nella scelta dell interfaccia di ascolto da implementare 2. Decidere qual è l origine dell evento: il componente o contenitore che può generare (notificare) l evento e creare tale oggetto GUI (ogni componente ad eccezione di LABEL o un contenitore ad esempio tutto l Applet). 3. Creare una oggetto della classe di ascolto: L oggetto ascoltatore può essere ad esempio tutta l Applet o tutta l applicazione che implementa (implements) la classe predefinita d ascolto di quell evento che ne definisce l interfaccia (metodi di risposta a quell evento). L oggetto ascoltatore può essere creato come istanza di una classe di ascolto definita dall utente che implementa (implements) la classe predefinita d ascolto di quell evento che ne definisce l interfaccia (metodi di risposta a quell evento) 4. Collegare all origine dell evento l oggetto della classe d ascolto di quell evento cioè registrare l ascoltatore 5. Implementare almeno un metodo dell interfaccia per rispondere a quell evento creando il codice di gestione che serve. Se sono definiti più metodi di risposta nell interfaccia, è necessario scrivere le segnature dei metodi non usati oppure, in alternativa, creare l oggetto ascoltatore come istanza di una classe che eredita (extends) dalla classe Adapter relativa a quell evento. Dispense on-line: Programmazione a oggetti in Java Cabri-Zambonelli
65 Leggere l input con la classe Scanner La classe Scanner Sfortunatamente, la classe InputStream non possiede metodi comodi per la ricezione di dati numerici e stringhe Per ovviare a questo inconveniente, Java 5.0 ha introdotto la classe Scanner nel package util. Un oggetto di tipo Scanner consente di leggere da qualsiasi flusso di ingresso (ad es. un file) senza rendere necessaria la gestione di ecccezioni. Si può usare anche per leggere dati in ingresso da tastiera ricevuti tramite l'oggetto System.in (di tipo InputStream adatto per la lettura di flussi di byte) Il metodo nextint di Scanner Prima di tutto si deve importare la classe Scanner all'interno del file.java che ne fa uso. import java.util.scanner; All'interno del codice si deve creare un nuovo oggetto della classe Scanner Scanner in = new Scanner(System.in); Poi si possono invocarne i metodi. Ad esempio per leggere un intero: int number = in.nextint(); Durante l esecuzione del metodo nextint il programma si ferma ed attende l introduzione dell input da tastiera, che termina quando l utente batte il tasto Invio Il metodo nextint restituisce un valore numerico di tipo int Cosa succede se l utente non digita un numero intero sulla tastiera (ad esempio, se scrive 55KZ)? Effetto senza cattura delle eccezioni: Effetto con cattura delle eccezioni: int intero = 0; try { intero= s.nextint(); catch (Exception e) { System.out.println("Errore: "+ e +" in input"); System.exit(0);
66 Altri metodi di Scanner ATTENZIONE: bisogna sempre importare la classe Scanner e creare un oggetto di tipo Scanner Leggere un numero in virgola mobile con separatore virgola double price = in.nextdouble(); Leggere una intera riga fino alla pressione di Enter String city = in.nextline(); Leggere una parola fino al primo carattere di spaziatura: spazio, fine riga, tabulazione String state = in.next(); Informare se esiste il token (blocco di testo categorizzato) successivo: boolean b = in.hasnext();
67 Uso finestre di dialogo: di input, di allarme o di scelta multipla La classe JOptionPane permette di creare facilmente una dialog box standard di tipo pop up che consente all utente di inserire dati o essere avvisato di qualcosa. Per informazioni sull uso di tale classe si consulti How to Make Dialogs, nella sezione del The Java Tutorial. Una dialog box appare, di solito, come mostrato a lato, ma si possono apportare modifiche al layout modificandone le proprietà con l impostazione di opportuni parametri dei metodi di tipo showxxxdialog icon message input value option buttons Parametri: parentcomponent, message, title, messagetype, optiontype, options, icon, initialvalue oltre a selectionvalues(opzioni di scelta in dialoghi di tipo input) parentcomponent: il Componente che contiene la dialog box; se tale primo parametro è null imposta il Frame di default usato come parent: la finestra di dialogo sarà centrata nello schermo e risulterà indipendente dal resto dell'applicazione. message: un messaggio descrittivo, di solito una stringa; con altre possibilità: Object[] cioè un array di oggetti interpretato come una serie di messaggi memorizzati in uno stack verticale.l interpretazione è ricorsiva: ogni oggetto è interpretato a seconda del tipo Component cioè un componente visualizzato nel dialog. Icon inglobata in un JLabel e visualizzata nel dialog altro cioè un oggetto convertito in una stringa mediante il metodo tostring. Il risultato è inglobato in un JLabel e visualizzato nel dialog title: il titolo della finestra di dialogo che appare nella cornice superiore; il valore di default dipende dal tipo di dialog (la stringa Input per dialog in input, Messaggio per dialog in out, Selezionare un opzione per dialog di conferma). messagetype : definisce lo stile del messaggio. Possibili valori, che prevedono relative icone di default, sono: ERROR_MESSAGE INFORMATION_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE PLAIN_MESSAGE optiontype: definisce il set dei bottoni di opzione (senza limiti) che appaiono in basso al dialog box: DEFAULT_OPTION YES_NO_OPTION YES_NO_CANCEL_OPTION OK_CANCEL_OPTION options: una più dettagliata descrizione del set dei bottoni di opzione. Di solito un array di stringhe ma è previsto un array di oggetti che possono essere di tipo: Component cioè un componente aggiunto direttamente al bottone Icon usata come label in un JButton altro cioè un oggetto convertito in una stringa mediante il metodo tostring. Il risultato è usato come label in un JButton icon: una icona decorativa. Il valore di default è stabilito dal parametro messagetype. initialvalue: la scelta di default (valore in input) La classe JOptionPane mette a disposizione tre tipi di pannelli: Confirm Dialog, Input Dialog e Message Dialog il primo tipo di pannello viene usato quando si deve chiedere all'utente di effettuare una scelta tra un gruppo di possibilità; il secondo torna utile quando si debba richiedere l'inserimento di una stringa di testo mentre il terzo viene usato per informare l'utente.
68 JOptionPane fornisce un gruppo di metodi statici che permettono di creare facilmente questi pannelli ricorrendo ad una sola riga di codice senza istanziare oggetti: Alcuni metodi showinputdialog per finestra di dialogo in lettura: static Object showinputdialog(component parentcomponent, Object message, String title, int messagetype, Icon icon, Object[] selectionvalues, Object initialselectionvalue) Prompts the user for input in a blocking dialog where the initial selection, possible selections, and all other options can be specified. static String showinputdialog(object message) Shows a question-message dialog requesting input from the user. static String showinputdialog(object message, Object initialselectionvalue) Shows a question-message dialog requesting input from the user, with the input value initialized to initialselectionvalue. JOptionPane.showInputDialog ("Come ti chiami?"); String nome; nome = JOptionPane.showInputDialog ("Come ti chiami?", "Mario"); // initialvalue è Mario Tra i metodi showconfirmdialog per finestra di dialogo che chiede di confermare una domanda tipo yes/no/cancel, il più semplice : static int showconfirmdialog(component parentcomponent, Object message) Brings up a dialog with the options Yes, No and Cancel; with the title, Select an Option. JOptionPane.showConfirmDialog(null, "Conferma");
69 Alcuni metodi showmessagedialog per finestra di informazione: static void showmessagedialog(component parentcomponent, Object message) Brings up an information-message dialog titled "Message". static void showmessagedialog(component parentcomponent, Object message, String title, int messagetype, Icon icon) Brings up a dialog displaying a message, specifying all parameters. JOptionPane.showMessageDialog(null, nome); JOptionPane.showMessageDialog (null, "Icona personalizzata", "Titolo del dialog", JOptionPane.INFORMATION_MESSAGE, new ImageIcon ("JavaCup.gif")); // icona (piccola immagine) personalizzata Il metodo showoptiondialog Grand Unification dei metodi precedenti static int showoptiondialog(component parentcomponent, Object message, String title, int optiontype, int messagetype, Icon icon, Object[] options, Object initialvalue) Brings up a dialog with a specified icon, where the initial choice is determined by the initialvalue parameter and the number of choices Tutte le finestre di dialogo (dialogs) create sono modali cioè ogni metodo showxxxdialog blocca il thread corrente fino a quando l interazione con l utente non è stata completata Esempio di applicazione con test di alcuni metodi di tipo showxxxdialog tra cui: finestra di dialogo in lettura con modifica del titolo di default della dialog box static String showinputdialog (Component parentcomponent, Object message, String title, int messagetype) finestra di dialogo in scrittura con modifica del titolo di default della dialog box static void showmessagedialog (Component parentcomponent, Object message, String title, int messagetype) uso del metodo che costituisce Grand Unification static int showoptiondialog (Component parentcomponent, Object message, String title, int optiontype, int messagetype, Icon icon, Object[] options, Object initialvalue)
70 import javax.swing.*; // per classi JOptionPane e ImageIcon class Dialog { private String input; public String getinput(){ // uso finestra di dialogo in lettura input=joptionpane.showinputdialog("digita la stringa"); // per stesso effetto... ma con titolo "Lettura"... invece di "Input" input=joptionpane.showinputdialog(null,"digita la stringa", "Lettura", JOptionPane.QUESTION_MESSAGE); // Mostra una finestra di dialogo che chiede all utente di selezionare una stringa Object[] possiblevalues = { "prima", "seconda" ; Object sel_input = JOptionPane.showInputDialog(null, "Scegli", "Lettura", JOptionPane.INFORMATION_MESSAGE, null, possiblevalues, possiblevalues[0]); input = sel_input.tostring(); return input; // oppure con casting input = (String) sel_input;
71 public void visualizza(string testo){ // uso finestra di dialogo in scrittura JOptionPane.showMessageDialog(null, testo, null, JOptionPane.PLAIN_MESSAGE ); // senza icona JOptionPane.showMessageDialog(null, testo); // icona di tipo "Informazione" // finestra di dialogo più flessibile Object[] options = { "OK", "CANCELLA" ; JoptionPane.showOptionDialog (null, testo, "Informazione", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); // icona di default JoptionPane.showOptionDialog (null, testo, "Informazione", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, new ImageIcon ("JavaCup.gif"), options, options[0]); public static void main (String arg[]){ Dialog o = new Dialog(); String messaggio = "Inserita: " + o.getinput(); o.visualizza(messaggio); // fine main // fine applicazione JOptionPane.showMessageDialog (null, "Icona personalizzata", "Titolo del dialog", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("JavaCup.gif")); // icona personalizzata
72 JButton b1 = new JButton("Bottone 1"); // Component come messaggio JOptionPane.showMessageDialog (null, b1, null, JOptionPane.INFORMATION_MESSAGE ); ImageIcon img = new ImageIcon("JavaCup.gif"); // icona come messaggio JOptionPane.showMessageDialog (null, img, null, JOptionPane.QUESTION_MESSAGE ); JOptionPane.showConfirmDialog(null, "Conferma"); JLabel labelicon = new JLabel(new ImageIcon("JavaCup.gif")); // icona - logo come etichetta Object[] options = {labelicon, b1, b2; JOptionPane.showOptionDialog (null, "Scegli", "Senza effetto", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); Object[] options1 = {img, b1, b2; // icona - logo in bottone che premuto chiude dialog JOptionPane.showOptionDialog (null, "Scegli bottone", "Senza effetto", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, new ImageIcon ("JavaCup.gif"), options1, options1[0]); // icona personalizzata NB: personalizzazione del set di bottoni di opzione posti in basso Per permettere opzioni di scelta in input, con metodo showinputdialog, volendo personalizzare l icona ad esempio col logo di Java (immagine JavaCup.gif di dimensioni 16x16, nella stessa cartella), il titolo: Object[] possiblevalues = { "uno", "due","tre"; JOptionPane.showInputDialog (null, "Messaggio", "Titolo", JOptionPane.INFORMATION_MESSAGE, new ImageIcon ("JavaCup.gif"), possiblevalues, possiblevalues[0]);
73 . con modifica del Look & Feel try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); catch (Exception e) { // stile CDE/Motif. Scelta disponibile su qualunque piattaforma Look & Feel : insieme delle due proprietà che caratterizzano un ambiente a finestre: l'aspetto dei componenti (ovvero la loro sintassi) specifiche di visualizzazione la maniera in cui essi reagiscono alle azioni degli utenti (la loro semantica) specifiche di interazione La natura multipiattaforma di java ha spinto i progettisti di Swing a separare le problematiche di disegno grafico dei componenti da quelle inerenti al loro contenuto informativo, con la sorprendente conseguenza di permettere agli utenti di considerare il Look & Feel come una proprietà del componente da impostare a piacere. La distribuzione standard del JDK comprende di base due alternative: Metal e Motif. La prima definisce un Look & Feel multipiattaforma, progettato per risultare familiare agli utenti di ogni piattaforma; la seconda implementa una vista familiare agli utenti Unix. Le distribuzioni di java per Windows e Mac includono anche un L&F che richiama quello della piattaforma ospite. Per impostare da programma un particolare look & feel è sufficiente chiamare il metodo UIManager.setLookAndFeel(String classname) passando come parametro il nome di un l&f installato nel sistema. Un applicazione che crea una finestra in cui si apre una dialog box modale che risulta centrata rispetto a quest ultima: import javax.swing.*; import java.awt.*; // per Container class DialogF extends JFrame { public void visualizza(){ // per aprire una finestra // nel punto x,y con larghezza 400, altezza 200 setbounds(100,100,400,200); Container cont=getcontentpane(); cont.setlayout(null); setvisible(true); String nome; nome = JOptionPane.showInputDialog (cont,"come ti chiami?", "Mario"); setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main (String arg[]){ DialogF o = new DialogF(); o.visualizza(); // fine main // fine applicazione
74 La stessa applicazione (che crea una finestra in cui si apre una dialog box modale che risulta centrata rispetto a quest ultima) con modifica del Look & Feel import javax.swing.*; import java.awt.*; // per Container class DialogF extends JFrame { public void visualizza(){ try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); catch (Exception e) { // stile CDE/Motif. Scelta disponibile su qualunque piattaforma // per aprire una finestra // nel punto x,y con larghezza 400, altezza 200 setbounds (100,100,400,200); Container cont=getcontentpane(); cont.setlayout(null); setvisible(true); String nome; nome = JOptionPane.showInputDialog (cont,"come ti chiami?", "Mario"); setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); public static void main (String arg[]){ DialogF o = new DialogF(); o.visualizza(); // fine main // fine applicazione nb: Due parole sui metodi per visualizzare o nascondere i frames : setvisible(true) per rendere visibile il frame che non lo è per default - deprecato show() setvisible(false) ovviamente per nasconderlo - deprecato hide() Per scegliere la posizione iniziale si può utilizzare il metodo setbounds(int, int, int, int); con argomenti nell'ordine di digitazione x ed y dell'angolo superiore sinistro e dimensioni larghezza ed altezza del frame
75 Progetto di un pannello che sia maschera di input /** * * Maschera classe che crea il pannello consentendo di: * inserire articoli (e relativo prezzo), sia in lire che in euro * avere sempre sott occhio il totale, sia in lire che in euro * poter salvare su file, in qualunque momento, l elenco degli ordini inseriti. * classe quarta /4/9 */ import java.io.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Maschera extends JPanel { JTextField nome, prezzo, totale; JTextArea elenco; JRadioButton lire, euro; ButtonGroup grp; JButton save, inserisci; Box boxradio, riga1, riga2, riga3, riga4; // Costruzione del primo Box orizzontale in cui collocare le due etichette public Maschera(){ super(); JLabel etichetta1 = new JLabel("Descrizione articolo"); JLabel etichetta2 = new JLabel("Prezzo"); riga1 = new Box(BoxLayout.X_AXIS); riga1.add(etichetta1); riga1.add(box.createhorizontalstrut(80)); // spazio fisso indivisibile di 80 pixel riga1.add(etichetta2); // Costruzione del secondo Box orizzontale in cui collocare i due campi di testo nome = new JTextField(15); prezzo = new JTextField(7); prezzo.sethorizontalalignment(jtextfield.right); riga2 = new Box(BoxLayout.X_AXIS); riga2.add(nome); riga2.add(prezzo); // Costruzione del terzo Box orizzontale con altre etichette riga3 = new Box(BoxLayout.X_AXIS); riga3.add(new JLabel("Articoli inseriti")); riga3.add(box.createhorizontalstrut(80)); riga3.add(new JLabel("Valuta")); //Costruzione del Box verticale per bottoni e totale // l area di testo elenco = new JTextArea(6,12); elenco.seteditable(false); // non modificabile elenco.setbackground(color.cyan); // i bottoni radio lire = new JradioButton("Lire",true); // default euro = new JRadioButton("Euro"); grp = new ButtonGroup(); grp.add(lire); grp.add(euro);
76 //Costruzione del Box verticale per bottoni e totale // il Box verticale vero e proprio boxradio = new Box(BoxLayout.Y_AXIS); boxradio.add(lire); boxradio.add(euro); boxradio.add(box.createverticalstrut(20)); boxradio.add(new JLabel("Totale")); totale = new JTextField("0", 5); // totale inizialmente a zero totale.sethorizontalalignment(jtextfield.right); boxradio.add(totale); // Costruzione del quarto Box orizzontale per area di testo e Box verticale riga4 = new Box(BoxLayout.X_AXIS); riga4.add(elenco); riga4.add(box.createhorizontalstrut(30)); riga4.add(boxradio); // Assemblaggio dei vari blocchi add(riga1); add(riga2); inserisci = new JButton("Aggiungi articolo"); add(inserisci); add(riga3); add(riga4); save = new JButton("Salva"); save.setenabled(false); // inizialmente disabilitato add(save); // Creazione e registrazione dei listener inserisci.addactionlistener (new InsertListener(nome, prezzo, totale,elenco, lire, save)); // in modo anonimo CurrencyListener c = new CurrencyListener(prezzo, totale); lire.addactionlistener(c); // unico listener per i due radio-button euro.addactionlistener(c); // unico listener per i due radio-button save.addactionlistener (new SaveListener(elenco, totale,lire, save)); // fine classe che estende JPanel class InsertListener implements ActionListener { JTextField nome, prezzo, totale; JTextArea elenco; JRadioButton lire; JButton save; public InsertListener (JTextField n, JTextField p, JTextField t, JTextArea e, JRadioButton l, JButton s){ nome=n; prezzo=p; totale=t; elenco=e; lire=l; save=s; public void actionperformed(actionevent e){ save.setenabled(true); double tot = Double.parseDouble(totale.getText()); double prz = Double.parseDouble(prezzo.getText()); totale.settext(double.tostring(prz + tot)); elenco.append (nome.gettext() + " " + prezzo.gettext() +(lire.isselected()? " ITL" : " EUR") + "\n"); nome.settext(""); prezzo.settext(""); nome.requestfocus(); // fine classe ascoltatore per inserimento nuovi articoli
77 class CurrencyListener implements ActionListener { JTextField prezzo, totale; public final double CAMBIO = ; public CurrencyListener(JTextField p,jtextfield t){ prezzo=p; totale=t; public void actionperformed(actionevent e){ double tot = Double.parseDouble(totale.getText()); String p = prezzo.gettext(); if (p.equals("")) p="0"; double price = Double.parseDouble(p); if (e.getactioncommand().equals("lire")) { // erano Euro, vanno convertiti in lire tot *= CAMBIO; price *= CAMBIO; // elimina la parte frazionaria di un numero reale, tot = Math.rint(tot); // arrotondandolo price = Math.rint(price); else { // erano Lire, da convertire in Euro tot /= CAMBIO; price /= CAMBIO; tot = Math.rint(tot*100)/100; price = Math.rint(price*100)/100; // Arrotondamento alla IIª cifra decimale: si sposta la virgola, si arrotonda e si rimette la virgola dov'era totale.settext (Double.toString(tot)); prezzo.settext(price==0.0? "" : Double.toString(price)); // Estetica: un prezzo di 0.0 non viene indicato, si mette le stringa vuota. // fine classe ascoltatore per conversione valuta class SaveListener implements ActionListener { JTextField totale; JTextArea elenco; JRadioButton lire; JButton save; public SaveListener(JTextArea e, JTextField t, JRadioButton l, JButton s){ elenco=e; totale=t; lire=l; save=s; public void actionperformed(actionevent e){ double tot = Double.parseDouble(totale.getText()); try { FileWriter f = new FileWriter("ELENCO.txt"); PrintWriter out = new PrintWriter(f); out.print(elenco.gettext()); out.println(); out.print("totale: " + totale.gettext() +(lire.isselected()? " ITL" : " EUR") + "\n"); out.println(); out.close(); catch (IOException ex) { System.err.println(ex); save.setenabled(false); // fine classe ascoltatore per salvataggio su file Di seguito la possibile classe di test cou scrittura su file senza gestione dell'a capo in Blocco note
78 /** * * TestMaschera application * quarte /4/15 */ import java.awt.*; import javax.swing.*; class TestMaschera { public static void main(string [] args){ JFrame f = new Jframe("Acquisti"); Container c = f.getcontentpane(); Maschera guip = new Maschera(); guip.setbackground(color. lightgray); c.add(guip); // sfondo del pannello colorato // aggiunge il pannello f.setsize(300,300); f.setvisible(true); f.setdefaultcloseoperation (JFrame.EXIT_ON_CLOSE); Ogni volta si riscrive sul file senza aggiungere:
79 Menu /** * * Menu application * Sun /5/4 */ // import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Menu { //Where the GUI is created JFrame f = new JFrame("Finestra con menu"); JMenuBar menubar; JMenu menu, submenu; JMenuItem menuitem; JRadioButtonMenuItem rbmenuitem; JCheckBoxMenuItem cbmenuitem; public Menu() { //Create the menu bar. menubar = new JMenuBar(); //Build the first menu. menu = new JMenu("Un menu"); menubar.add(menu); //a group of JMenuItems menuitem = new JMenuItem("Solo testo"); menuitem.setaccelerator(keystroke.getkeystroke(keyevent.vk_a, ActionEvent.CTRL_MASK)); // modifica per Ctr A //menuitem.getaccessiblecontext().setaccessibledescription("this doesn't really do anything"); // non appare 1.5 menu.add(menuitem); menuitem = new JMenuItem("Sia testo sia icona", new ImageIcon("middle.gif")); //menuitem.setmnemonic(keyevent.vk_b); // non appare 1.5 menu.add(menuitem);
80 menuitem = new JMenuItem(new ImageIcon("middle.gif")); // immagine nella stessa cartella del bytecode menu.add(menuitem); //a group of radio button menu items menu.addseparator(); ButtonGroup group = new ButtonGroup(); rbmenuitem = new JRadioButtonMenuItem("Un radio button come voce di menu"); rbmenuitem.setselected(true); group.add(rbmenuitem); menu.add(rbmenuitem); rbmenuitem = new JRadioButtonMenuItem("Un altro"); group.add(rbmenuitem); menu.add(rbmenuitem); //a group of check box menu items menu.addseparator(); cbmenuitem = new JCheckBoxMenuItem("Una check box come voce di menu"); menu.add(cbmenuitem); cbmenuitem = new JCheckBoxMenuItem("Un'altra"); menu.add(cbmenuitem); //a submenu menu.addseparator(); submenu = new JMenu("Un sottomenu"); menuitem = new JMenuItem("Una voce del sottomenu"); menuitem.setaccelerator(keystroke.getkeystroke(keyevent.vk_2, ActionEvent.ALT_MASK)); // per Alt submenu.add(menuitem); menuitem = new JMenuItem("Un altra voce"); submenu.add(menuitem); menu.add(submenu); //Build second menu in the menu bar. menu = new JMenu("Un altro menu"); menu.settooltiptext ("Senza voci"); menubar.add(menu); Container c= f.getcontentpane(); f.setsize(400,300); f.setjmenubar(menubar); f.setvisible(true); public static void main (String args[]){ new Menu();
BorderLayout. 1 Gestori di Layout http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html (guida visuale)
Posizionamento diretto di un elemento GUI o tramite gestori di layout Nel posizionamento diretto (dipendente dalle impostazioni grafiche del sistema) non abbiamo bisogno di un gestore di layout (layout
Eventi di azione. // con interfaccia per eventi di azione
Eventi di azione (Interfaces ActionListener, Classes ActionEvent) Sono generati quando si premono bottoni, si selezionano voci di menù, si preme invio mentre si scrive in un campo di testo. In awt sono
I Canvas. import java.awt.*; import javax.swing.*; public class Graf{ public Graf () { JFrame f = new JFrame("Finestra"); // crea frame invisibile
I Canvas Tra i vari contenitori Java il Canvas (area di disegno o tela) è una semplice superficie di disegno particolarmente utile per visualizzare immagini o per effettuare altre operazioni grafiche.
I Layout Manager di java. Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni
I Layout Manager di java Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni Creazione di interfacce complesse con i layout manager La posizione di un componente aggiunto
L Abstract Windowing Toolkit. Le GUI in Java. Il Frame. Cenni sull ereditarietà. Gianpaolo Cugola - Sistemi Informativi in Rete
Le GUI in Java L Abstract Windowing Toolkit Fino ad ora abbiamo usato le classi del pacchetto JavaBook per realizzare semplici interfacce grafiche (GUI) Si tratta di classi facili da usare...... ma che
Programmazione in rete e laboratorio
Programmazione in rete e laboratorio 2001-02 JAVA Alberto Martelli PROGRAMMAZIONE GRAFICA Molti programmi interagiscono con l utente attraverso una interfaccia grafica GUI - Graphical User Interface Java
Java GUI. Swing Java
Java GUI Swing Java 1 Introduzione n Componenti grafici di Java (Swing) Utilizzo di alcuni dei metodi per creare semplici finestre grafiche Accesso ai JavaDoc per usare meglio gli oggetti già pronti n
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE La Gestione degli Eventi Ogni oggetto grafico è predisposto ad essere sollecitato in qualche modo dall utente (per esempio un pulsante può essere premuto).
GUI e java swing. Elmenti della GUI. Eventi e listener contenitori componenti layout manager. caratteristiche speciali
GUI e java swing Raffaella Brighi, a.a. 2005/06 Corso di Laboratorio II. A.A. 2005-06 CdL Operatore Informatico Giuridico. Elmenti della GUI Eventi e listener contenitori componenti layout manager caratteristiche
La nostra finestra dovrebbe essere come mostra la figura: Diamo innanzitutto un occhiata alle componenti principali di input/output:
Esercitazione N4: Costruzione di una applicazione GUI utilizzando i componenti di base per realizzare l input e l output e cioè Label, TextBox, TextArea Button e Panel (Pannelli) I componenti che utilizzeromo
L interfaccia grafica con Java
L interfaccia grafica con Java 1/24 L interfaccia utente serve per la comunicazione tra utente e programma Distinguiamo le interfacce tra quelle a caratteri e quelle grafiche Le GUI (Graphical user interface)
Sviluppo di Interfacce Grafiche in Java
Sviluppo di Interfacce Grafiche in Java Massimiliano de Leoni (con la supervisione del docente Massimo Mecella) Università di Roma La Sapienza - Sede di Latina Corso di Progettazione del Software A.A.
Gestione di eventi ed interfacce utente grafiche
Gestione di eventi ed interfacce utente grafiche Eventi Ogni volta che l utente esegue un azione un clic del mouse la pressione di un tasto sulla tastiera la modifica di una finestra la selezione di un
Riassunto. GUI in Java con l AWT 1. Cos è una GUI. Oggi: GUI in Java, l AWT. GUI in Java. Un esempio. Stefano Mizzaro 1
Riassunto GUI in Java con l AWT 1 Stefano Mizzaro Dipartimento di matematica e informatica Università di Udine http://www.dimi.uniud.it/mizzaro [email protected] Programmazione, lezione 23 15 febbraio
Eventi e listener per i componenti grafici
Eventi e listener per i componenti grafici Raffaella Brighi, a.a. 2005/06 Corso di Laboratorio II. A.A. 2005-06 CdL Operatore Informatico Giuridico. Eventi e listener Eventi e listener (ascoltatori) sono
Programmazione ad Oggetti. JFrame è la classe di base per le finestre Fornisce tutte le caratteristiche di una finestra vuota
Programmazione ad Oggetti Interfacce grafiche V 1.2 Marco Torchiano 2005 JFrame JFrame è la classe di base per le finestre Fornisce tutte le caratteristiche di una finestra vuota Barra del titolo Pulsanti
Introduzione al package grafico Swing
Introduzione al package grafico Swing Architettura di javax.swing Java supporta direttamente nella propria architettura il concetto di applicazione grafica, tramite il package javax.swing, in cui i componenti
Java Applet. Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A. 2009-2010
Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A. 2009-2010 Alessandro Longheu http://www.diit.unict.it/users/alongheu [email protected] Java Applet 1 Application VS Applet Una
Grafica swing in Java
Grafica swing in Java JFrame Costruttori public JFrame() Crea un nuovo Frame inizialmente invisibile public JFrame(Stringtitle) Crea un nuovo frame, inizialmente invisibile, con un testo specificato. Metodi
Prof. Pagani Corrado ESERCITAZIONI JAVA
Prof. Pagani Corrado ESERCITAZIONI JAVA PRIMA APPLICAZIONE CONSOLE Eseguire somma e media tra tre numeri ES 1 CODICE Non programmo sfruttando il paradigma ad oggetti (ho solo il metodo main che è static
Swing. Swing 1. Java e la grafica Java permette di realizzare agevolmente applicazioni grafiche Package java.awt
Swing Swing 1 Java e la grafica Java permette di realizzare agevolmente applicazioni grafiche Package java.awt il primo package grafico (Java 1.0) indipendente dalla piattaforma... o quasi! Package javax.swing
Programmazione Java: Interfacce grafiche (GUI)
Programmazione Java: Interfacce grafiche (GUI) [email protected] http://www.di.univaq.it/romina.eramo/tlp ( 1 ) (GUI) Interfacce grafiche Rendere facili le cose semplici e possibili le cose difficili
Esercitazione n 6. Capacità di analisi e di estensione di progetti Componenti grafici e gestione di eventi Linguaggio Java:
Esercitazione n 6 Capacità di analisi e di estensione di progetti Componenti grafici e gestione di eventi Linguaggio Java: il package javax.swing (JFrame, JPanel, JButton, ) java.util.eventobject e sue
Le basi della grafica in Java. Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni
Le basi della grafica in Java Prof. Francesco Accarino IIS Altiero Spinelli via Leopardi 132 Sesto san Giovanni Elaborazione classica o imperativa L elaborazione è concentrata nel momento centrale, durante
Riassunto. GUI in Java con l AWT 1. Oggi: GUI in Java, l AWT. Oggi. GUI in Java. Cos è una GUI. Stefano Mizzaro 1
Riassunto GUI in Java con l AWT 1 Stefano Mizzaro Dipartimento di matematica e informatica Università di Udine http://www.dimi.uniud.it/mizzaro/ [email protected] Programmazione, lezione 20 20 novembre
Corso sul linguaggio Java
Corso sul linguaggio Java Modulo L6 (JAVA9) 1 Introduzione alle applet 1 Prerequisiti Architettura client/server Elementi di base HTML Programmazione Java Utilizzo package awt di Java 2 1 Introduzione
Campo Minato. in java
Campo Minato in java Il gioco campo rettangolare o quadrato suddiviso in tanti quadratini Il giocatore deve sminare il campo, cliccando sui quadratini, col tasto destro o col tasto sinistro il gioco cliccando
APPLICAZIONI & APPLET
APPLICAZIONI & APPLET Java è un ottimo linguaggio per costruire applicazioni anche non per Internet anche non grafiche ma si è diffuso storicamente, e trae forza, dal concetto di applet come piccola (?)
Gestione degli eventi in Java
Gestione degli eventi in Java package java.awt.event.* Il modello degli eventi I componenti dell awt generano eventi in seguito alle azioni dell utente movimento del mouse click pressione di un tasto etc.
PROVA FINALE Ingegneria del software
PROVA FINALE Ingegneria del software Ing. Jody Marca [email protected] Laboratorio N 3 Cosa faremo oggi 2 Interfaccia grafica e SWING Lettura e scrittura di Files di properties Internazionalizzazione
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE
INTERFACCE GRAFICHE IN JAVA CON SWING DISPENSE INTRODUZIONE L interfaccia grafica del programma è composta dai cosiddetti componenti GUI (Graphics User Interface); essi sono dei componenti che servono
Alessandro De Luca. Lezione, 13 maggio 2015
Basi Basi di di dati dati ee sistemi sistemi informativi informativi II mod.laboratorio mod.laboratorio Alessandro De Luca Università degli Studi di Napoli Federico II Lezione, Introduzione a Java Swing
Classi astratte. Master in Web Technology e Security luglio - settembre 2000. Interfacce
Master in Web Technology e Security luglio - settembre 2000 JAVA Alberto Martelli Parte III Programmazione grafica Classi astratte Vogliamo implementare un algoritmo di ordinamento di un array che sia
Interfacce grafiche. Una GUI (Graphic User Interface) contiene vari componenti: bottoni, etichette, immagini...
Interfacce grafiche Una GUI (Graphic User Interface) contiene vari componenti: bottoni, etichette, immagini... Alcuni componenti ne contengono altri (ad esempio le finestre), e sono detti contenitori.
TECNOLOGIE APPLICAZIONI WEB Linguaggio Java: Le Applet
Università degli Studi di Modena e Reggio Emilia Facoltà di Ingegneria Reggio Emilia CORSO DI TECNOLOGIE APPLICAZIONI WEB Linguaggio Java: Le Applet Prof. Franco Zambonelli Lucidi realizzati in collaborazione
Corso sul linguaggio Java
Corso sul linguaggio Java Modulo JAVA5 B1 Gestione eventi 1 1 Prerequisiti Programmazione base in Java Utilizzo di classi e oggetti AWT o Swing Programmazione ad eventi 2 1 Introduzione Le interfacce create
Grafico della parabola
Grafico della parabola Il grafico matematico è un disegno che mostra l andamento di una funzione f(x) al variare della variabile x. Per tracciare un grafico sul video del computer, si deve scegliere un
Programmazione Orientata agli Oggetti in Linguaggio Java
Programmazione Orientata agli Oggetti in Linguaggio Java Programmazione Grafica: Componenti versione 1.0 Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)
interfacce ed eventi intercettare il mouse ed altri eventi
interfacce ed eventi intercettare il mouse ed altri eventi interfacce: premessa il termine "interfaccia" occorre in Java con due significati, collegati ma distinti 1. interface, parola chiave di Java e
Autore: Prof. Agostino Sorbara ITIS "M. M. Milano" Polistena (RC)
In questa lezione introduciamo alcuni strumenti che Java rende disponibili per la creazione di interfacce utente a manipolazione diretta, dette anche WYSISYG (what you see is what you get), con un elevato
Marco Faella Elementi di programmazione di interfacce Grafiche. Il pattern OBSERVER.
Marco Faella Elementi di programmazione di interfacce Grafiche. Il pattern OBSERVER. 9 Lezione n. Parole chiave: Java Corso di Laurea: Informatica Insegnamento: Linguaggi di Programmazione II Email Docente:
Gestione dell interattività: gli eventi
Gestione dell interattività: gli eventi Gli eventi sono una modalità di comunicazione tra l utente (sistema) e il programma in esecuzione. Tipi di eventi: Input da parte dell utente: pressione del(i) bottone(i)
INSERIRE I DATI NEL DATABASE
13-Cap10_DWCS3.qxd 18-11-2009 11:43 Pagina 201 CAPITOLO10 INSERIRE I DATI NEL DATABASE In questo capitolo In questo capitolo imparerai a interagire con i contenuti del database gestiti nel sito. In particolare
L interfaccia grafica in Java
L interfaccia grafica in Java Java possiede due package per la creazione di interfacce grafiche java.awt javax.swing AWT (Abstract Widget Toolkit) presente già in Java 1.0, migliorato in Java 1.1. Invariato
GUI e java swing. Templates per GUI degli IDE. Gli IDE forniscono Template per generare interfacce grafiche.
GUI e java swing Raffaella Brighi, a.a. 2006/07 Corso di Laboratorio II. A.A. 2006-07 CdL Operatore Informatico Giuridico. Templates per GUI degli IDE Gli IDE forniscono Template per generare interfacce
Windows. La prima realizzazione di un ambiente grafico si deve alla Apple (1984) per il suo Macintosh. La gestione dei file conserva la logica del DOS
Windows La prima realizzazione di un ambiente grafico si deve alla Apple (1984) per il suo Macintosh La gestione dei file conserva la logica del DOS Funzionalità di un S.O. Gestione dei file Gestione dei
! Programmazione strutturata. ! OO: TDA, scambio messaggi, eredità, polimorfismo, OO in Java. ! Rassegna API. ! Documentazione Javadoc delle API
Riassunto Applet (e altro dell AWT ) Stefano Mizzaro Dipartimento di matematica e informatica Università di Udine http://www.dimi.uniud.it/mizzaro/ [email protected] Programmazione, lezione 22 19 maggio
AWT: Abstract Window Toolkit
AWT: Abstract Window Toolkit E una libreria che offre le componenti GUI essenziali Tutte le componenti GUI che sono visualizzabili sono sottoclassi della classe astratta Component Container è una sottoclasse
Introduzione. Java. G. Prencipe
Java creare finestre G. Prencipe [email protected] Introduzione L obiettivo originale delle librerie per interfacce grafiche utente (GUI) in Java1.0 era di permettere al programmatore di costruire interfacce
Java Interfaccia Grafica
Java Interfaccia Grafica Testi di consultazione: a) core Java 1.1 (Volume I Fundamentals) Cay S. Horstmann, Gary Cornell, Prentice Hall, 1997. b) Java 1.2 Unleashed, Jamie Jaworski, Sams Publishing, 1998.
GRAFICA ED EVENTI SWING, AWT e JavaFX
GRAFICA ED EVENTI SWING, AWT e JavaFX argomenti JavaFX: architettura e gerarchia Componenti principali: Stage, Scene, contenuti Gestione degli eventi Java Package Grafici I package grafici che comprende
Programmazione ad Eventi
Programmazione ad Eventi Eventi, Sorgenti, e Listeners Una interfaccia utente deve gestire una moltitudine di eventi eventi da tastiera, del mouse, click su pulsanti, Opportuno poter discriminare diversi
Modulo o Form in Html
Pagina dinamica E un documento contenente oggetti, dati e informazioni che possono variare anche in base all iterazione dell utente con il documento stesso. Un esempio classico è quello di una persona
