Introduzione a Java ed Eclipse - 2

Selezionare File->Import

Immagine slide

Se non è già aperta, aprire la cartella General

Immagine slide

Viene creata la cartella del progetto. Aprire Eclipse

Immagine slide

Esportare ed Importare progetti

  • Per esportare un progetto, basta farne un archivio .zip o .tgz della directory del progetto, che si ntrova all'interno della directory del workspace.
  • Entreremo in Eclipse ed eseguiremo i passi delle seguenti slide
  • Per importare un progetto per prima cosa metteremo, ad esempio sulla scrivania, l'archivio del progetto preparato in precedenza
  • Scompatteremo l'archivio, riottenendo, sempre sulla scrivania, la cartella del progetto.

Esportare ed Importare progetti

  • Alla fine potremo anche cancellare l'archivio e la cartella scompattata

Selezionare la cartella del progetto e cliccare Ok

Immagine slide

Selezionare Copy projects into workspace

Immagine slide

Cliccare con il tasto destro e scegliere Estrai qui

Immagine slide

Selezionare Browse per scegliere il file

Immagine slide

Protarsi sulla scrivania

Immagine slide

Selezionare Existing Project into Workspace e cliccare su Next>

Immagine slide

Possiamo vedere ora il progetto nella lista

Immagine slide

FlowLayout in azione

Immagine slide

Confermare con Finish

Immagine slide

La risposta al bottone

  • Nel momento in cui cerchiamo di inserire la riga closeButton.addActionListener(this);, viene segnalato un errore in quanto il parametro di assActionListener deve essere appunto un ActionListener.
  • La nostra classe non è un ActionListener e deriva da JFame, qundi come possiamo farla derivare da ActionListener?
  • Per fortuna ActionListener non è una class ma una interface. Possiamo quindi aggiungere la dipendenza con la parola chiave implements.
  • Una classe può estendere una sola classe padre, ma può implementare quante interfacce vuole.

La risposta al bottone

  • Per fare scomparire questo errore, dovremo aggiungere il metodo, richiesto dall'interfaccia, public void actionPerformed(ActionEvent evt) che verrà richiamato dal bottone, quando verrà premuto.
  • Nel momento in cui aggiungiamo alla classe implements ActionListener scompare l'errore sulla addActionListener ma ne compare uno sulla classe.

Il metodo actionPerformed

  • Il metodo che abbiamo aggiunto, actionPerformed, riceve un parametro di tipo ActionEvent, che contiene i dati del pulsante premuto.
  • Questo metodo verrà richiamato da tutti i bottoni che assoceremo alla nostra finestra per la risposta. Come facciamo allora a sapere che bottone è stato premuto?
  • Ci viene in aiuto il metodo getSource() di ActionEvent, che ci indica quale bottone ha generato l'evento.

Il metodo actionPerformed

  • Se noi confrontiamo il valore ritornato da getSource() con tutti i bottoni che abbiamo associato alla finestra, scopriremo quale è stato premuto e quindi che azione fare.
  • Nel nostro caso, quando il bottone è closeButton, potremo terminare il programma con il metodo dispose();.

Facciamo un esempio concreto: un bottone in una finestra

  • Quando premiamo un bottone in un'interfaccia grafica, esso dovrà richiamare un metodo dell'applicazione per eseguire il suo lavoro.
  • In Java, una finestra deriva dalla classe JFrame. Creeremo una nuova classe MyButtonFrame, derivata da JFrame, che conterrà il nostro bottone.
  • Questa classe (oltre ad avere serialVersionUID, richiesto dalla classe padre, avrà un attributo JButton closeButton; che conterrà il nostro bottone

Facciamo un esempio concreto: un bottone in una finestra

  • Nel costruttore:
    • assegneremo un titolo alla finestra con invocando il metodo setTitle
    • assegneremo un bottone all'attributo closeButton tramite la new JButton("Termina");, chiamando il costruttore che assegna un nome al bottone
    • indicheremo al bottone di richiamare questa classe per indicare la pressione tramite il metodo closeButton.addActionListener(this);
    • aggiungeremo il bottone alla finestra tramite il metodo add(closebutton);
    • per finire richiederemo alla finestra di dimensionarsi correttamente tramite il metodo pack();

FlawLayout

  • Proviamo ora a creare due bottoni, Ok e Termina, ed inserirli uno accanto all'altro con un FlowLayout.

FlawLayout

  • Il sorgente della finestra, nel file MyFrameFlow.java diventa il seguente:
    package frameflawtest;

    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame;

    public class MyFrameFlaw extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;

    private JButton closeButton;
    private JButton okButton;

    public MyFrameFlaw() {
    setTitle("Finestra con form di prova");

    setLayout(new FlowLayout());

    closeButton = new JButton("Termina");
    closeButton.addActionListener(this);
    add(closeButton);
    okButton = new JButton("Ok");
    okButton.addActionListener(this);
    add(okButton);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    System.out.println("Termina");
    dispose();
    } else if (evt.getSource() == okButton) {
    System.out.println("Ok");
    dispose();
    }
    }
    }

FlawLayout

  • Per quanto riguarda il main, basta cambiare il nome della classe, quindi non lo riporto.

Il risultato (la finestrella in angolo in alto a sinistra)

Immagine slide

JLabel e JTextFiled in azione: premendo "Ok"

Immagine slide

Codice della classe MyButtonFrame

  • Nel file MyButtonFrame.java scriveremo:
    package framebuttontest;

    import java.awt.event.ActionEvent;

    public class MyButtonFrame extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;

    private JButton closeButton;

    public MyButtonFrame() {
    setTitle("Finestra con form di prova");

    closeButton = new JButton("Termina");
    closeButton.addActionListener(this);
    add(closeButton);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    dispose();
    }
    }
    }

Le interfacce

  • In molti contesti, specie per gestire le interfacce grafiche, si fa uso delle cosiddette funzioni di callback
  • Un esempio non legato alla grafica è la funzione qsort del C che richiede una funzione di callback che indichi l'ordine di due elementi.
  • Trasportando la qsort in Java, la funzione di callback maggioreDi dovrebbe tramutarsi in un metodo maggioreDi degli orrgetti da ordinare.

Le interfacce

  • In C++ otterremmo questo metodo utilizzando l'ereditarietà multipla: creeremmo una classe Confrontabile che contenga il metodo virtuale puro maggioreDi e creeremmo una classe che derivi sia dal suo naturale padre che da maggioreDi
  • In Java l'ereditarietà multipla manca, ma per risolvere il problema di garantire che una classe fornisca uno o alcuni metodi necessari, si utilizzano le interfacce.

Classe FrameButtonTest e main

  • Questa classe sarà estremamente semplice. Conterrà esclusivamente il metodo main che si limiterà a creare una istanza di MyButtonFrame e visualizzarla.
  • Nel file FrameButtonTest.java scriveremo:
    package framebuttontest;

    public class FrameButtonTest {
    public static void main (String[] args) {
    MyButtonFrame f = new MyButtonFrame();

    f.setVisible(true);
    }

    }

GridLayout

  • Ora proviamo a mettere i due bottoni uno sopra l'altro con un GridLayout di 2 righe ed 1 colonna

GridLayout

  • Il codice, nel file MyFrameGrid.java scriveremo:
    package framegridtest;

    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame;

    public class MyFrameGrid extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;

    private JButton closeButton;
    private JButton okButton;

    public MyFrameGrid() {
    setTitle("Finestra con form di prova");

    setLayout(new GridLayout(2,1));

    closeButton = new JButton("Termina");
    closeButton.addActionListener(this);
    add(closeButton);
    okButton = new JButton("Ok");
    okButton.addActionListener(this);
    add(okButton);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    System.out.println("Termina");
    dispose();
    } else if (evt.getSource() == okButton) {
    System.out.println("Ok");
    dispose();
    }
    }
    }

GridLayout

  • Ancora, il main richiede solo la modifica della classe, quinidi non lo riporto.

Introduciamo del testo: JLabel e JTextField

  • Per fare qualcosa di più utile occorre in primo luogo poter visualizzare del testo nella pagina ed in secondo luogo poter fare scrivere del testo all'utente.
  • Per il primo scopo potremo utilizzare il componente JLabel.
  • Il costruttore di JLabel prende in ingresso una String (normalmente una stringa tra apici) e scrive dove viene posizionato il testo della stringa.
  • Se poi vogliamo modificare in un secondo tempo il testo visualizzato, basta utilizzare il metodo setText di JLabel.

Introduciamo del testo: JLabel e JTextField

  • Per ottenere invece un testo dall'utente useremo JTextField.
  • Nel codice del bottone che eseguirà l'azione, potremo leggere il testo scritto dall'utnete utilizzando il metodo String getText(); di JTextField.
  • Normalmente su utilizza il costruttore di default, per ottenere un campo vuoto.

Disposizione dei componenti: i layout manager

  • Per ora abbiamo inserito un unico compnente in una finestra. Ma se volessimo inerirne diversi?
  • In Java i componenti non vengono inseriti in posizione fissa, come in Visual Basic. Piuttosto vengono disposti utilizzando delle regole di posizionamento.
  • Queste regole vengono implemetate utilizzando delle classi derivate da LayoutManager, associate ad una finestra o ad un altro contenitore tramite il metodo setLayout();

Disposizione dei componenti: i layout manager

  • Esistono molti LayoutManager. Noi ne vedremo in dettaglio tre:
    • FlowLayout che affianca i componenti, senza allargarli e centrandoli se lo spazio è maggiore del necessatio
    • GridLayout che crea una tabella di elementi consentendo di metterli su più righe e colonne, tutte di dimensione uguale, estendendo i componenti inseriti alla dimensione della cella
    • BorderLayout che suddivide la finestra in un'area centrale, estesa al massimo, e quattro aree periferiche, ridotte al minimo

Aggiungiamo liste e checkbox

  • Per completare la limitata panoramica dei componenti di interfaccia, aggiungo le liste per effettuare le scelte (JComboBox) e i box di spunta (JCheckbox)
  • Per effettuare una scelta tra una serie limitata di opzini predeterminate si utilizzerà un JComboBox.
  • Lo possiamo creare con il costruttore di default. Potremo poi aggiungere le singole voci utilizzando il metodo addItem(Object item); passando le String delle voci.

Aggiungiamo liste e checkbox

  • Una volta creata ed inizializzata la lista, potremo conoscere la scelta dell'utente tramite il metodo int getSelectedIndex(); che ritornerà l'indice tra le scelte inserite selezionato dall'utente.
  • Altrettanto, per creare un box di spunta utilizzeremo il costruttore di default di JCheckBox.
  • Quando poi dobbiamo sapere se l'utente ha spuntato o no la scelta chiameremo il metodo boolean isSelected();

BorderLayout e JPanle in azione

Immagine slide

Disposizioni più sofisticate: BorderLayout e JPanel

  • E se volessimo disporre i componenti in maniera un po' più flessibile?
  • La soluzione è quella di prepararci dei piccoli gruppi di componenti, disposti in un riquadro invisibile, usando un LayoutManager e poi inserire questi riquadri invisibili in un riquadro di livello superiore o nella finestra.
  • Il riquadro invisibile, cui associare il LayoutManager ed inserire i componenti è JPanel.

Disposizioni più sofisticate: BorderLayout e JPanel

  • Proviamo a modificare il layout dell'esempio precedente nel seguente modo:
    • Associare un BorderLayout al JFrame
    • Mettere la JLabel con il prompt ed il JTextField nella stessa riga
    • Inserire questi due elementi nella zona BorderLayout.NORTH del JFrame
    • Impostare a 10 caratteri la dimensione del JTextField per evitare che venga disegnato troppo piccolo
    • Mettere la JLabel con il risultato nella zona BorderLayout.CENTER del JFrame
    • Inserire i due bottoni affiancati nella zona BorderLayout.SOUTH del JFrame

Disposizioni più sofisticate: BorderLayout e JPanel

  • Per ottenere questa disposizione dovremo:
    • creare due JPanel
    • asscoiare un FlowLayout a ciascun JPanel
    • aggiungere il JLabel ed il JTextField al primo JPanel
    • Aggiungere al JFrame il primo JPanel nella zona BorderLayout.NORTH
    • Aggiungere i due JButton la secondo JPanel
    • Aggiungere il secondo JPanel al JFrame nella zona BorderLayout.SOUTH

BorderLayout e JPanle in azione 1

Immagine slide

GridLayout in azione

Immagine slide

Esempio con JLabel e JTextField

  • Scriveremo nel file MyFrameField.java il codice:
    package framefieldtest

    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame
    import javax.swing.JLabel;
    import javax.swing.JTextField;

    public class MyFrameField extends JFrame implements ActionListener {

    private JButton closeButton;
    private JButton helloButton;
    private JTextField nameField;
    private JLabel replay;

    private static final long serialVersionUID = 1L;

    public MyFrameField () {
    setTitle("Finestra con form di prova");

    closeButton = new JButton("Ok");
    helloButton = new JButton ("Saluti...");
    nameField = new JTextField();
    replay = new JLabel("Attendo");

    closeButton.addActionListener(this);
    helloButton.addActionListener(this);

    setLayout(new GridLayout(5,1));
    add(new JLabel("Scrivi il tuo nome"));
    add(nameField);
    add(replay);
    add(helloButton);
    add(closeButton);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    dispose();
    } else if (evt.getSource() == helloButton) {
    replay.setText("Ciao " + nameField.getText());
    }
    }

    }

Esempio con JLabel e JTextField

  • Ancora una volta il main cambia solo nel nome della classe e quindi non lo riscrivo.
  • Proviamo questi due componenti. Scriviamo un programma che:
    • Presenti all'utente un campo per inserire il proprio nome, con una label che indichi cosa deve fare l'utnete
    • Presenti un bottone "OK" che Scrive "Ciao " seguito dal nome in un'altra label
    • Presenti un bottone per terminare

Liste e Box di spunta in azione

Immagine slide

Un esempio con liste e box di spunta - il codice

  • Nel file MyFrameCheckAndList.java inseriremo il codice:
    package framecheckandlisttest;

    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;

    public class MyFrameCheckAndList extends JFrame implements ActionListener {

    private JButton closeButton;
    private JButton helloButton;
    private JTextField nameField;
    private JLabel replay;
    private JCheckBox confidenziale;
    private JComboBox sesso;

    private static final long serialVersionUID = 1L;

    public MyFrameCheckAndList () {
    setTitle("Finestra con form di prova");

    closeButton = new JButton("Ok");
    helloButton = new JButton ("Saluti...");
    nameField = new JTextField();
    nameField.setColumns(10);
    replay = new JLabel("Attendo");
    confidenziale = new JCheckBox();
    sesso = new JComboBox();
    sesso.addItem("Maschio");
    sesso.addItem("Femmina");

    closeButton.addActionListener(this);
    helloButton.addActionListener(this);

    setLayout(new BorderLayout());
    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(new JLabel("Scrivi il tuo nome"));
    p.add(nameField);
    add(p, BorderLayout.NORTH);

    add(replay, BorderLayout.CENTER);

    JPanel pannelloInferiore = new JPanel();
    pannelloInferiore.setLayout(new GridLayout(3,1));
    p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(confidenziale);
    p.add(new JLabel("Tono confidenziale"));
    pannelloInferiore.add(p, BorderLayout.NORTH);
    pannelloInferiore.add(sesso);
    p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(helloButton);
    p.add(closeButton);
    pannelloInferiore.add(p);
    add(pannelloInferiore, BorderLayout.SOUTH);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    dispose();
    } else if (evt.getSource() == helloButton) {
    String saluto="";
    switch (sesso.getSelectedIndex()) {
    case 0: // Maschio
    if (confidenziale.isSelected()) {
    saluto="Ciao caro ";
    } else {
    saluto = "Buon giorno Signor ";
    }
    break;
    default:
    if (confidenziale.isSelected()) {
    saluto="Ciao cara ";
    } else {
    saluto = "Buon giorno Signora ";
    }
    break;
    }
    replay.setText(saluto + nameField.getText());
    }
    }
    }

Un esempio con liste e box di spunta - il codice

  • Come al solito nel main va solo cambiato il nome della classe, quindi non lo riporto.

Esempio di disposizioni più sofisticate: BorderLayout e JPanel

  • Inseriremo nel file MyFrameBorder.java il seguente codice:
    package framebordertest;

    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;

    public class MyFrameBorder extends JFrame implements ActionListener {

    private JButton closeButton;
    private JButton helloButton;
    private JTextField nameField;
    private JLabel replay

    private static final long serialVersionUID = 1L;

    public MyFrameBorder () {
    setTitle("Finestra con form di prova");

    closeButton = new JButton("Ok");
    helloButton = new JButton ("Saluti...");
    nameField = new JTextField();
    nameField.setColumns(10);
    replay = new JLabel("Attendo");

    closeButton.addActionListener(this);
    helloButton.addActionListener(this);

    setLayout(new BorderLayout());
    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(new JLabel("Scrivi il tuo nome"));
    p.add(nameField);
    add(p, BorderLayout.NORTH);
    add(replay, BorderLayout.CENTER);
    p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(helloButton);
    p.add(closeButton);
    add(p, BorderLayout.SOUTH);
    pack();
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == closeButton) {
    dispose();
    } else if (evt.getSource() == helloButton) {
    replay.setText("Ciao " + nameField.getText());
    }
    }
    }

Esempio di disposizioni più sofisticate: BorderLayout e JPanel

  • Come al solito in main va solo modificato il nome della classe, quindi non la riporto.

JLabel e JTextField in azione

Immagine slide

Un esempio con liste e box di spunta

  • Aggiungeremo quindi alla nostra interfaccia:
    • Un JComboBox con le voci "Maschio" e "Femmina"
    • Un JCheckBox con la JLabel "Tono confidenziale"
    • Un JPanel con un GridLayout per inserire nella zona BorderLayout.SOUTH i tre elementi aggiuntivi
    • Un ulteriore JPanel con un FlowLayout per affiancare il JCheckBox alla sua JLabel
  • Per provare liste e box di spunta possiamo aggiungere al programma precedente la possibilità di scegliere il sesso della persona da salutare e un saluto formale o informale.

Un esempio con liste e box di spunta

  • Poi nel codice che gestisce il JButton "Saluti..." valuteremo lo stato della JComboBox e del JCheckBox per scegliere il saluto opportuno.

Liste e Box di spunta in azione 3

Immagine slide

Liste e Box di spunta in azione 2

Immagine slide
[any material that should appear in print but not on the slide]