Input ed eventi.

Lo scopo principale di un'applicazione informatica sta nella capacità di risolvere una classe di problemi in modo veloce e sicuro. I problemi della stessa classe hanno soluzioni diversa a seconda del valore di uno o più parametri iniziali in base ai quali sviluppare l'applicazione e pervenire a uno o più risultati conseguenti. Bisogna quindi che un'applicazione, diversamente dagli esempi proposti nelle pagine precedenti, sia di volta in volta in grado di acquisire dagli utenti i valori iniziali di questi parametri.

La situazione più semplice è quella in cui un'applicazione acquisisce i valori di questi parametri, rappresentati da stringhe numeriche o alfanumeriche, direttamente da tastiera e viene attivata da un click su un bottone.

Per acquisire caratteri dalla tastiera è disponibile la classe JTextField visualizzata nel componente che la contiene da un campo che, se selezionato, mostra di seguito i caratteri premuti sulla tastiera.

Per recepire i click dal mouse dell'utente è disponibile la classe JButton. Ad ogni bottone puà essere associato un comando con il metodo JButton.setActionCommand(String actionCommand). Un click sul bottone genera un evento che deve essere captato dall'applicazione. A questo scopo l'applicazione deve essere dorata dell'interfaccia ActionListener e di un metodo public void actionPerformed(ActionEvent e) che, a seconda dell'evento captato, specifichi l'opportuna risposta. Se la risposta è una stringa alfanumerica può essere assegnata al testo di un componente JLabel.

Per esemplificare i concetti proposti si propone un'applicazione che, dato l'anno che deve essere successivo alla riforma gregoriana del calendario, calcola la data della Pasqua cattolica per quell'anno.

La sequenza di preparazione dell'applicazione è la seguente.

L'aspetto grafico dell'applicazione è il seguente

fig01.gif

Una volta preparato l'aspetto grafico dell'applicazione, bisogna specificare come essa reagisce agli input dell'utente, compilando il metodo actionPerformed(ActionEvent e) in cui si specifica che, se il comando non è "reset" bisogna rilevare l'anno scritto in textfield_input e, se possibile, calcolare la data della Pasqua corrispondente.

Bisogna quindi preparare una funzione che in base ai necessari calcoli astronomici, produca l'output corrispondente da assegnare come testo a label_outout.

 


Provare il seguente esempio.


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
//==========================================================================
public class Pasqua
extends JFrame
implements ActionListener 

{
  Container contenitore;
  JPanel pannello_intestazione, pannello_input, pannello_output;
  JLabel label_intestazione, label_output;
  JTextField textfield_input;
  JButton button_reset, button_calcolo;
  static String[] nome_mese =
    {"","Gennaio","Febbraio","Marzo","Aprile", "Maggio","Giugno","Luglio","Agosto","Settembre",
     "Ottobre", "Novembre","Dicembre"};

//--------------------------------------------------------------------------
  public Pasqua()
    {
      setTitle("Pasqua");
      int larghezza = 300;
      int altezza = 140;
      setPreferredSize(new Dimension(larghezza,altezza));
      contenitore = getContentPane();
      setResizable(false);
      altezza = 32;

      contenitore.setLayout(new BoxLayout(contenitore,BoxLayout.Y_AXIS));
      pannello_intestazione = new JPanel();
      pannello_intestazione.setPreferredSize(new Dimension(larghezza,altezza));
      pannello_intestazione.setBackground(new Color(70,180,80));
      pannello_intestazione.setBorder(BorderFactory.createRaisedBevelBorder());
      label_intestazione = new JLabel("Data della Pasqua cattolica");
      pannello_intestazione.add(label_intestazione);
      add(pannello_intestazione);

      pannello_input = new JPanel();
      pannello_input.setPreferredSize(new Dimension(larghezza,altezza));
      pannello_input.setBackground(new Color(90,160,90));
      pannello_input.setBorder(BorderFactory.createRaisedBevelBorder());
      pannello_input.setLayout(new BoxLayout(pannello_input,BoxLayout.X_AXIS));
      button_reset = new JButton(" RESET ");
      button_reset.setBackground(Color.yellow);
      button_reset.addActionListener(this);
      button_reset.setActionCommand("reset");
      pannello_input.add(button_reset);
      textfield_input = new JTextField();
      pannello_input.add(textfield_input);
      button_calcolo = new JButton("CALCOLO");
      button_calcolo.setBackground(Color.red);
      button_calcolo.setActionCommand("calcolo");
      button_calcolo.addActionListener(this); 
      pannello_input.add(button_calcolo);
      add(pannello_input);

      pannello_output = new JPanel();
      pannello_output.setPreferredSize(new Dimension(larghezza,altezza));
      pannello_output.setBackground(new Color(30,220,140));
      pannello_output.setBorder(BorderFactory.createRaisedBevelBorder());
      label_output = new JLabel(" ");
      pannello_output.add(label_output);
      add(pannello_output);
    }
//--------------------------------------------------------------------------
  public void actionPerformed(ActionEvent e)
    {
      String comando= e.getActionCommand();
      if (comando=="reset")
        {
          textfield_input.setText("");
          label_output.setText("");
          return;
        };
      String input = textfield_input.getText();
      String data = dataPasqua(input);
      if (data.length()==0)
        label_output.setText(input+": input non ammesso.");
      else
        label_output.setText(data);
    }

//--------------------------------------------------------------------------
 String dataPasqua(String input) 
   {
     int anno;
     try
       {
         anno = Integer.parseInt(input);
       }
     catch(NumberFormatException ecc)
       {
         return "";
       }
     int numero_oro = anno % 19;
     int secolo = anno/100;
     int epatta = (secolo- secolo/4 - (8*secolo+13)/25 + 19*numero_oro + 15) % 30;
     int luna_piena = epatta - (epatta/28)*(1-(29/(epatta+1))*((21-numero_oro)/11));
     int correzione = (anno + anno/4 + luna_piena + 2 - secolo + secolo/4) % 7;
     int differenza = luna_piena - correzione; 
     int mese = 3 + (differenza+40)/44;
     int giorno = differenza + 28 - 31*(mese/4);
     String data = "Pasqua: "+giorno+" "+nome_mese[mese]+" "+anno;
     return data;
   }
//--------------------------------------------------------------------------

  public static void main(String args[])
    {
      Pasqua p = new Pasqua();
      p.pack();
      p.setVisible(true);
    }
}
//==========================================================================

fig03.gif

Scrivendo 2020 nel campo di input e cliccando "CALCOLO" si ottiene

fig02.gif