Chiamata dell'applet: il comando APPLET

Il comando <APPLET> viene usato per aggiungere un applet Java nella propria pagina Web. Questo richiede un comando </APPLET> corrispondente. Il parametro CODE dà il nome del file contenente l'applet compilato. HEIGHT e WIDTH specificano la dimensione della finesta nella quale compare l'applet. Ad esempio:
       <APPLET CODE="HelloWorldApplet.class" HEIGHT=50 WIDTH=150>
       Peccato:con un browser Java qui vedreste un applet!
       </APPLET>

Netscape assume che l'applet si trova nella stessa directory dove si trova il documento HTML contenente l'applet. Se non è così il parametro CODEBASE deve contenere l'URL della directory che contiene il compilato(il valore di CODE è sempre un nome di file che finisce con .class non un URL).
Talvolta tutti i files dell'applet potrebbero essere zippati in un unico file archivio di tipo jar. In questo caso si usa il parametro: archive=nomearchivio.jar. L'eventuale scritta tra <APPLET> e </APPLET> viene inserita per avvisare un utente senza Java della presenza dell'applet:un browser Java invece ignora questi messaggi.

Un applet può usare dei parametri che permettono di adattarlo alle proprie esigenze (come quando si chiama una routine).Questi sono specificati usando uno o più comandi <PARAM> tra <APPLET> e </APPLET>. All'interno devono essere presenti NAME e VALUE:

<PARAM NAME="param-name" VALUE="param-value">

C++--

Al livello della singola routine,Java e' molto simile al C.E' possibile compilare una routine Java in C con pochissime modifiche. Al livello di programma, Java e' un linguaggio a oggetti molto simile al C++. Si dice che l'autore di Java abbia preso il C++ , gli ha tolto le cose inutili,ha aggiunto la garbage collection e il risultato e' stato Java.

I tipi di dati fondamentali in Java sono:

Tipi di dati Java

Tipo Valore Valore di default Dimensione Classe Wrapper
boolean true, false false 1 bitBoolean
char Unicode character \u0000 16 bitsCharacter
byte signed integers 0 8 bitsByte
short signed integers 0 16 bitsShort
int signed integers 0 32 bitsInteger
long signed integers 0 64 bitsLong
float floating point 0.0 32 bitsFloat
double floating point 0.0 64 bitsDouble

I caratteri Unicode permettono di rappresentare i maggiori alfabeti mondiali.

Le classi wrapper servono quando dobbiamo usare un tipo primitivo come oggetto. A queste classi sono inoltre associati dei metodi utili per fare operazioni di conversione. Ad esempio per convertire un intero n in una stringa di caratteri str , si scrive:

 int n = 134;
 String str = Integer(n).toString();

Istruzioni Java

Applicazioni Java

La maniera migliore per imparare Java è di cominciare con i programmi tradizionali,applicazioni nel gergo Java:sono molto meno complessi degli applets.
Che ne dite di cominciare col solito programma CiaoATutti?
class CiaoATutti{
      public static void main (String args[]){
            System.out.println("Ciao a tutti");
     }
  }
Create un piccolo file di testo con queste righe chiamandolo CiaoATutti.java, poi date i comandi:
javac CiaoATutti.java
java CiaoATutti
e il gioco è fatto!
Se siete ai primi passi con la programmazione e' probabile che non riusciate a capire come seguire le istruzioni precedenti:per questo ho inserito a parte delle istruzioni dettagliate.

Ora che il ghiaccio e' rotto, proviamo a scrivere un programma che somma 2 numeri: cioè noi scriviamo

java Somma 2 3 
e otteniamo la somma dei 2 numeri.
class Somma{
       public static void main(String args[]){
       int a, b, c;
       a = Integer.parseInt(args[0]);
       b = Integer.parseInt(args[1]);
       c = a + b;
       System.out.println("La somma di"+a+"+"+b+"e'"+c);
       }
   }

Ora vogliamo scrivere un programma che fa la media di un numero qualsiasi di numeri (interi) in ingresso:
java Media 43 23 51 68 
class Media {
      public static void main(String args[]){
      int n = args.length;
      int totale = 0 ;
      double media = 0f;
      if( n > 0) {
        for (int i = 0; i < n; i++){
          totale += Integer.parseInt(args[i]);
          }
         media = (float)totale/n;
       }
      System.out.println("La media e'" + media);
   }
 }

Possiamo scrivere la parte che calcola la media come una subroutine:
class Media1 {
      public static void main(String args[]){
      System.out.println("La media e'" + media(args));
      }
      static double media (String args[]){
        int n = args.length;
        int totale = 0;
        if (n > 0 ) {
           for (int i = 0; i < n; i++){
          totale += Integer.parseInt(args[i]);
          }
         return((float)totale/n);
         }
        else return(0f);
       }
    }

Programmazione a oggetti Java

Facendo un salto come complessità passiamo alla programmazione a oggetti. Un programma invece di essere dei dati e delle routines e' un insieme di oggetti che comunicano mandadosi messaggi. L'idea di base e' che un oggetto descrive un "oggetto di tutti i giorni" con una serie di dati e una serie di routines che trattano questi dati. Nel gergo un oggetto e' definito da una classe con proprieta' e metodi. Le proprieta' non sono altro che delle variabili che descrivono l'oggetto mentre potete pensare ai metodi come azioni che l'oggetto puo' fare o meglio comandi che gli potete inviare. (In effetti la differenza tra metodo e routine e' che un metodo e' una routine collegata a un singolo oggetto).Ora passiamo all'equivalente del programma CiaoATutti della programmazione a oggetti:un programma che non fa niente se non descrivere qualche oggetto della vita di tutti i giorni,in questo caso la moto.
/*classe Moto*/
class Moto{
     String marca;
     String colore;
     boolean motoreacceso;
   
  /*il costruttore*/
    
     Moto(String m, String c){
         marca = m;
         colore = c;
         motoreacceso = false;
        }

  /*metodi*/
     void mostraTipo(){
         System.out.println("La marca di questa moto e' "+marca+" e il suo colore e' "+colore);
         if(motoreacceso == true)
            System.out.println(".Essa ha il motore acceso.");
         else
            System.out.println(".Essa ha il motore spento.");
        }
     
     void accendiMotore(){
         if (motoreacceso == true)
            System.out.println("Il motore e' gia' acceso");
           else {
              motoreacceso = true;
              System.out.println("Ora il motore e' acceso");
                }
      }
      
 /*main*/
     public static void main(String args[]){
      Moto a = new Moto("Ducati","rossa");
      Moto b = new Moto("Piaggio","blu");
      
      a.mostraTipo();
      a.accendiMotore();
      a.mostraTipo();
      b.accendiMotore();
      b.mostraTipo();

 }
}
In questo caso le proprieta' sono marca, colore e motoreacceso mentre i metodi sono mostraTipo e accendiMotore.
Il costruttore e' invece un metodo speciale che ha lo stesso nome della classe ed e' richiamato quando si crea un oggetto (dopo "new") per inizializzare le variabili che descrivono lo stesso.In Java cioe' per creare un nuovo oggetto bisogna dichiararlo e quindi chiamare il costruttore. Vedi sopra:
 Moto a = new Moto("Ducati","rossa");
Nota i messaggi all'oggetto creati con la notazione nome_dell_oggetto.nome_del_metodo() ad es. a.accendiMotore().
Ed ora un esempio piu' utile. Riscriveremo il programma che fa la media di una serie di numeri in modo da utilizzare una classe SerieNumeri.
public class SerieNumeri{
      private int serie[];
      private int n;
/*costruttore*/
      public SerieNumeri(String s[]){
       n = s.length;
       serie = new int[n];
       for (int i=0 ;i < n; i++){
         serie[i] = Integer.parseInt(s[i]);
         }
       }
      /*media*/
      public double media(){
      int totale = 0;
      for(int i=0; i < n; i++){
         totale += serie[i];
         }
      return((float)totale/n);
     }
 }


public class Media2{
      static SerieNumeri a;
    
      public static void main(String args[]){
       a = new SerieNumeri(args);
       System.out.println("La media e' "+a.media());
      }
  }
Le due classi vanno scritte su due diversi files SerieNumeri.java e Media2.java. Per compilare ed eseguire usa i comandi:
javac SerieNumeri.java  Media2.java
java Media2 2 4 8 5 63

Gli applet finalmente!

Scrivere un programma che faccia uso di mouse,grafica,etc come un applet e' ancora piu' difficile. Bisogna conoscere le librerie di classi disponibili e quali sono le classi che vanno usate o modificate e quali metodi saranno usati dal "sistema" per comunicare col vostro programma.
Inoltre un messaggio puo' essere inviato anche dall'utente tramite un evento come cliccare col mouse e bisogna conoscere tutti gli eventi e come devono essere trattati nel programma.Un evento,in Java, e' un oggetto ed esso e' associato a due altri oggetti:l'oggetto source(sorgente) che genera l'evento e l'oggetto listener che tratta l'evento. Gli oggetti grafici di AWT possono essere sorgente di una serie di eventi,ognuno dei quali e' caratterizzato da un nome.Ad esempio l'oggetto Button puo' generare gli eventi Action ,Focus,Key,Mouse e Component. Listener puo' essere invece una qualsiasi classe:basta che inizi con :
Class PincoPallino implements TipoeventoListener... 
Si dice in gergo che essa implementa l'interfaccia TipoeventoListener, nel senso che contiene delle (ri)definizioni di una serie di metodi predefiniti per trattare un certo tipo di evento.Quindi e' importante conoscere i nomi degli eventi e dei metodi ad essi associati.

Ad esempio per scrivere il classico CiaoATutti sotto forma di applet dobbiamo sapere che:

  1. Il browser si aspetta che gli scriviate una classe modificando quella di libreria chiamata "JApplet"
  2. Il disegno all'interno dell'applet deve essere fatto in una classe che modifica "JPanel"
  3. Il metodo init dell'applet deve creare il JPanel e definirlo come "contentPane" dell'applet
  4. Per dipingere il contenuto dell'applet il browser chiama il metodo(routine) paintComponent della classe che modifica il JPanel che va percio' ridefinita.
  5. La classe "Graphics" permette di disegnare definendo un "contesto grafico" con metodi come drawString etc.

import java.awt.*;
import javax.swing.*;
public class CiaoATutti1 extends JApplet {

 Display disegno;
 
 public void init(){
  disegno = new Display();  
  setContentPane(disegno);
 }
class Display extends JPanel {
 public void paintComponent(Graphics g){
   g.drawString("CiaoATutti",5,25);
  }
 }
 }

Una semplicissima interazione come una scritta che segue il mouse,richiede le seguenti conoscenze:
  1. Quando l'utente fa "qualcosa" il browser richiama un particolare metodo dell'oggetto listener per quell'evento.In questo caso "mouseMoved" dell'interfaccia "MouseMotionListener".
    Ma perche' questo accada sono necessarie 3 cose:
    1. L'oggetto "listener" deve essere aggiunto alla lista di listener nell'oggetto che genera l'evento usando il metodo addTipoeventoListener.
    2. La classe di oggetti "listener" deve implementare l'interfaccia "TipoeventoListener".
    3. Tutti i metodi dell'interfaccia devono essere ridefiniti:non solo quello che serve.
  2. Le informazioni su cosa e' successo sono passate alla routine attraverso un oggetto Tipoevento (in questo caso MouseEvent).
  3. Per aggiornare il disegno nella finestra occorre chiamare repaint() ; non paint() ! che puo' essere chiamata solo dal browser .
  4. Prima che il JPanel dell'applet sia disegnato da paintComponent() ,il browser richiama una routine init() dove possiamo inizializzare le nostre variabili e fare un primo disegno dell'applet.
  5. Possiamo ottenere le dimensioni dell'applet con getSize().width e getSize.height

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Mousedemo extends JApplet implements MouseMotionListener{

 Display disegno;
 
 int mousex , mousey;

 public void init(){
   mousex=0;
   mousey=getSize().height - 20;
   disegno = new Display();  
   setContentPane(disegno);
   disegno.addMouseMotionListener(this);
   disegno.repaint();
   }
 public void mouseMoved(MouseEvent e){
    mousex = e.getX();
    mousey = e.getY();
    disegno.repaint();
    }
 public void mouseDragged(MouseEvent e){
    }
 class Display extends JPanel {
 public void paintComponent(Graphics g){
   g.setColor(Color.white);
   int width =  getSize().width;
   int height = getSize().height;
   g.fillRect(0,0,width,height);

   g.setColor(Color.black);  
    g.drawString("CiaoATutti",mousex,mousey);
    }
 }
 }



Sempre piu' difficile!Ora aggiungiamo un tasto che quando viene pigiato fa riscrivere la scritta in un colore scelto a caso.
  1. Viene fornita una classe Button. Button("scritta") permette di crearlo con una scritta.
  2. actionPerformed(ActionEvent e) di ActionListener puo' essere usata per rispondere al tasto .
  3. Possiamo usare il metodo add(oggetto) per aggiungere nella finestra dell'applet il tasto.
  4. Per definire i colori esiste un oggetto Color e vari metodi come g.setColor.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Pigiami extends JApplet implements ActionListener{
  Display disegno;
  JButton tasto;
  Color colore;

  public void init(){
     disegno = new Display();  
     setContentPane(disegno);
     disegno.add(tasto = new JButton("pigiami!"));
     tasto.addActionListener(this);
     colore = new Color(0,0,0);
     disegno.repaint();
     }
  public void actionPerformed(ActionEvent e){
     colore = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
        disegno.repaint();
        }
class Display extends JPanel {
  public void paintComponent(Graphics g){
        g.setColor(Color.white);
        int width =  getSize().width;   
        int height = getSize().height; 
        g.fillRect(0,0,width,height);

        g.setColor(colore);
        g.drawString("CiaoATutti",20,50);
       }
 }
 }




Questa pagina e' stata aggiornata all'sdk 1.3 . Qui la versione per Java 1.1 e per java 1.0.2 .

Java Packages

The JDK contains:

Tipo di evento(*) Metodi associati(**)
ActionactionPerformed
AdjustmentadjustmentValueChanged
ComponentcomponentHidden
componentShown
componentMoved
componentResized
ContainercomponentAdded
componentRemoved
FocusfocusGained
focusLost
KeykeyPressed
keyReleased
keyTyped
Mouse(***)mouseClicked
mouseEntered
mouseExited
mousePressed
mouseReleased
MouseMotion(***)mouseDragged
mouseMoved
WindowwindowOpened
windowClosing
windowClosed
windowActivated
windowDeactivated
windowIconified
windowDeiconified
ItemitemStateChanged
TexttextValueChanged
(*)Il nome dell'interfaccia e' TipoEventoListener ad esempio:ActionListener
(**)Il metodo va ridefinito nel modo seguente:

public void metodo(TipoeventoEvent e) ad es:
public void mouseMoved(MouseEvent e)

Creazione di un applet non triviale in Java

Tutta la documentazione su questo applet e' reperibile a partire da questo documento di Datamation dove c'e' anche il codice sorgente originale delle 3 classi:

Di seguito trovate una breve introduzione in Italiano al materiale originale scritto in inglese.

Qui abbiamo in termini di oggetti:

Il posizionamento dei 3 componenti nell'applet e' fatto col metodo setLayout(oggetto_di_posizionamento). Per evitarci la fatica di dover definire questo "oggetto_di_posizionamento" Java ce ne fornisce 5 o 6 gia' predefiniti.In questo caso viene usato "BorderLayout". Dopodiche' bastano una serie di add("posizione",oggetto) con posizione North/Sud/East/West/Center per posizionare i vari elementi.

Infine notiamo come JPanel ha un metodo paintComponent da ridefinire per fare il disegno del grafico. Invece per gestire l'azione di premere il tasto possiamo usare direttamente (all'interno della classe GraphicButton il metodo actionPerformed che gestisce questo tipo di eventi .


Questa e' la versione aggiornata per JDK 1.3 e superiori. Qui la versione precedente per JDK 1.1

Sorgente di ChartTool

// ChartTool.java - defines top level applet class for Bar Chart tutorial
//
// Code Developed for the Java Tutor article in Java Report Magazine
// Copyright (c) 1996 by Philip Meese, All Rights Reserved
//
import java.awt.*;      // references to Java packages we use
import java.awt.event.*;
import javax.swing.*;

import BarChart;        // references to our classes
import NumericSet; 

//
// the ruling class
//
public class ChartTool extends JApplet {

        // member data
        NumericSet      _set;
        BarChart        _barChart;
        JTextField       _textField;
        GraphItButton   _button;
        final static int _width=200, _height=225;       // only works in appletviewer

        public void init(){
                _set=new NumericSet();                  // initialize member data
                resize(_width, _height);                // size the app window
                getContentPane().setLayout(new BorderLayout());          // create a layout mgr

                _textField=new JTextField();             // input fld
                _textField.setText("12 24 15 76 54 15");// sample data for starters
                getContentPane().add("North", _textField);

                _barChart=new BarChart(_set, _width, 150);
                getContentPane().add("Center", _barChart);

                _button=new GraphItButton(this, "Graph It");
                getContentPane().add("South", _button);

                graphIt();                              // show sample data
        }
        // called to update graph
        public void graphIt(){
                String s=_textField.getText();          // get user input
                _set.setFromString(s);                  // reinitialize NumericSet obj
                _barChart.numericSet(_set);             // update the BarChart's NumericSet
        }       
} // end class ChartTool

//
// button to perform graphing
//
class GraphItButton extends JButton implements ActionListener{
        ChartTool _app;

        // constructor
        public GraphItButton(ChartTool app_, String label_){
                setLabel(label_);
                _app=app_;
                addActionListener(this);
        }
        // this member function is called when the button is pressed
        public void  actionPerformed(ActionEvent e){
                _app.graphIt();
                }
} // end class GraphItButton

//eof

Sorgente di BarChart


//
// BarChart.java - defines BarChart class
//
// Code Developed for the Java Tutor column in Java Report 
// and Datamation Magazine
//
// Copyright (c) 1995 by Philip Meese
//
import java.awt.*;      // referece to the Abstract Window Toolkit pkg
import javax.swing.*;      // referece to the Abstract Window Toolkit pkg

import NumericSet;      // ref to our own class

public class BarChart extends JPanel {
        // member data
        NumericSet      _set;
        Rectangle       _rect;          // our bounds (bounding rectangle)
        int             _margin=5;      // for t, b, l and r margins

        // member functions
        public BarChart(NumericSet set_, int width_, int height_){
                numericSet(set_);
                setBounds(0, 0, width_, height_);
        }
        public void numericSet(NumericSet set_){
                _set=set_;
                repaint();
        }
        public void paintComponent(Graphics g_){
                _rect=getBounds();
                paintBackground(g_, Color.white);
                if(_set.length()>0)
                        paintBars(g_);
        }
        public void paintBars(Graphics g_){
                int sep=2;              // interbar spacing
                Color c=g_.getColor();  // remember color for later

                // area within which the bars will be rendered
                int renderWidth=_rect.width-_margin*2-(_set.length()-1)*sep;
                int renderHeight=_rect.height-_margin*2;

                int barWidth=renderWidth/_set.length();
                
                // scaling factor so values fit in given height
                float scaleFactor=(float)renderHeight/_set.max();

                Point barOrg=new Point(_margin, _margin);
                for(int i=0; i<_set.length(); i++, barOrg.y=_margin){
                        int barHeight=(int)(_set.value(i)*scaleFactor);

                        // adjust bar rect so it grows from bottom
                        barOrg.y=_margin+renderHeight-barHeight;

                        g_.setColor(Color.black);               // outline bar
                        g_.drawRect(barOrg.x, 
                                    barOrg.y, 
                                    barWidth-sep, 
                                    barHeight);

                        g_.setColor(Color.red);                 // fill bar
                        g_.fillRect(barOrg.x+1,
                                    barOrg.y+1, 
                                    barWidth-sep-1, 
                                    barHeight-1);

                        barOrg.x += barWidth + sep;             // space between
                }
                g_.setColor(c); //reset color
        }
        public void paintBackground(Graphics g_, Color c_){
                Color c=g_.getColor();
                g_.setColor(c_);
                g_.fillRect(0, 0, _rect.width, _rect.height);
                g_.setColor(c);
        }

} // end class BarChart


// debugging code no longer needed
/*
                debugPrintln("_rect.x/y/w/h=" + _rect.x + " "+  _rect.y +
                         " "+  _rect.width + " "+  _rect.height);


        public void debugPrintln(String s_){
                if(_debug>0) System.out.println(s_);
        }

                debugPrintln("paintBars: barWidth=" + barWidth + 
                        ", _rect.height=" + _rect.height +
                        ", _rect.width=" + _rect.width);
                debugPrintln("        scaleFactor=" + scaleFactor +
                        ", _set.length()=" + _set.length() +
                        ",_set.max()=" + _set.max() );

 */

Sorgente di NumericSet


//
// NumericSet.java - class NumericSet definition
//
// Code Developed for the Java Tutor column in Java Report Magazine
// Copyright (c) 1996 by Philip Meese, All Rights Reserved
//

public class NumericSet {
        // member data
        private int     _length=0;      // actual no of elemts in set
        private int     _maxLength=25;  // capacity of set
        private int     _set[];         // internal storage array
        private boolean         _debug=false;   // off by default

        // member functions
        //

        // constructor
        public NumericSet(){
                _set=new int[_maxLength];
        }

        // parses a string with integers seperated by spaces in it
        public void setFromString(String s_){
                int idx=0, idxSpace=0;
                for(_length=0; _length<_maxLength && idx < s_.length(); _length++){
                        // find end of first token
                        idxSpace=s_.indexOf(" ", idx);
                        if(idxSpace == -1) idxSpace=s_.length();        // end of string

                        _set[_length]=Integer.parseInt(s_.substring(idx, idxSpace));

                        // eat white space
                        while(s_.length() > ++idxSpace && 
                              !Character.isDigit(s_.charAt(idxSpace)))
                          ;
                        idx=idxSpace;
                }
        }

        // returns the value of a member of the set
        public int value(int idx_){
                if(idx_ >= _length)     return 0;
                else                    return _set[idx_];
        }

        // returns the maximum value in the set
        public int max(){
                int maxValue=0;
                for(int i=0;i<_length; i++)
                        if(maxValue<_set[i]) maxValue=_set[i];
                return(maxValue);
        }

        public int length() { return _length; }

        public void dump(){
                System.out.println(getClass().getName() + ": " );
                for(int i=0; i<_length; i++)
                        System.out.println("   Elemt #" + i + "=" + _set[i]);
        }

        public void debugPrintln(String s_){
                if(_debug) System.out.println(s_);
        }

} // end of class NumericSet