PkLab.net
Meccatronica
Italy - Basilicata - Matera
 
Robotica&Image processing Sistemi di controllo Applicazioni speciali Networking Didattica
 
Home e contatti
   
Introduzione a JDK 1.1.x

Esercitazioni di laboratorio del corso di Ingegneria del Software per gli studenti del 3^ anno del Diploma di Laurea in Ingegneria Informatica ed Automatica
Politecnico di Milano - Sede Cremona

docente titolare del corso prof.C.Ghezzi - Politecnico di Milano
Nota: questo materiale è di proprietà di Pk Lab ed è utilizzabile liberamente a condizione di citarne la fonte

INDICE

  1. Introduzione a Java 1.1.x
  2. AWT - Abstract Windowing ToolKit
  3. Gestione di eventi dell'interfaccia utente (Java 1.02)
  4. JDBC API (Application Program Interface)

Introduzione a Java 1.1.x

Configurazione

  • Lanciare l'installazione eseguendo il file eseguibile
  • Aggiungere nel PATH
C:\JDK1.1.x\BIN
  • Impostare la variabile d’ambiente
 SET CLASSPATH=.;C:\JDK1.1.x\CLASSES.ZIP

CONVENZIONI GENERALI

  • OGNI FILE SORGENTE DEVE CONTENERE UNA CLASSE
  • OGNI CLASSE DEVE CONTENERE UN METODO MAIN O DEVE ESSERE UNA ESTENSIONE DI UNA CLASSE ESISTENTE CHE A SUA VOLTA CONTIENE UN MAIN
  • IL FILE DEVE AVERE LO STESSO NOME DELLA CLASSE
  • JAVA E’ CASE SENSITIVE ANCHE PER I NOMI DEI FILE
  • UN FILE SORGENTE JAVA DEVE AVERE ESTENSIONE .JAVA
  • UN FILE COMPILATO HA ESTENSIONE .CLASS


IL PRIMO PROGRAMMA JAVA

CREARE UNA PROPRIA DIRECTORY DI LAVORO (Es. javaex)

APRIRE UN EDITOR DI TESTO QUALSIASI E SCRIVERE IL SEGUENTE PROGRAMMA

class HelloWorld 
{
  public static void main (String args[])
  {
    System.out.println("Hello World!");
  }
}

SALVARE NELLA DIRECTORY DI LAVORO IL FILE CON IL NOME HelloWorld.java


COMPILAZIONE DI UN PROGRAMMA JAVA

  • Il compilatore JAVA traduce il file sorgente .java in un file oggetto .class per la macchina virtuale java
  • Questo vuol dire che JAVA non genera un file eseguibile direttamente dal sistema operativo
  • JAVA genera un file che viene interpretato e da un programma (la macchina virtuale JAVA) che e’ poi in grado di eseguire il file .class
  • Nella versione JDK 1.1.x di Sun
    • Il compilatore JAVA è JAVAC
    • L’interprete JAVA e’ JAVA

entrambi i file sono eseguibili dal sistema operativo e sono in \JDK1.1.x\BIN

...HelloWorld

per la compilazione ed esecuzione di HelloWorld, i passi da seguire sono molto semplici (tutto dalla shell di DOS):

COMPILAZIONE

C:\JAVAEX>javac HelloWorld.java

ESECUZIONE (e verifica)

C:\JAVAEX>java HelloWorld
HelloWorld!
C:\JAVAEX>

Se non ci sono errori di sintassi il compilatore non ritorna alcun messaggio e se il programma e’ scritto correttamente l’interprete stampa a video la frase HelloWorld su una nuova riga


CLASSI ed OGGETTI

Una classe e’ una rappresentazione astratta di un entita’ concreta

In generale una classe e’ composta da ATTRIBUTI e METODI.

Gli attributi descrivono le caratteristiche dell'entita'

I metodi forniscono l’accesso a tali caratteristiche

GLI ATTRIBUTI DI UNA CLASSE POSSONO ESSERE MODIFICATI SOLO DAI METODI DELLA CLASSE STESSA (INFORMATION HIDING)

Un istanza o oggetto di una classe e’ una delle entita’ descritte dalla classe

Una classe descrive la struttura di un oggetto ed e’ unica per quell’oggetto

Ogni oggetto appartenente alla stessa classe puo' assumere valori diversi per tutti gli attributi di cui e’ composto

ESEMPIO: LA CLASSE Motorcycle

Creiamo una classe per descrivere una moto

CLASSE: Motorcycle

ATTRIBUTI: modello,colore,statoMotore

METODI:Motore ON, MotoreOFF, MostraAttributi

ESEMPIO: MotorCycle.java

ESERCIZIO: modificare il main in modo da creare almeno due oggetti, instanziarli e usarne i metodi. Creare altri metodi ad esempio: stopEngine()


UN SEMPLICE APPLET

Un APPLET e’ un programma JAVA che viene eseguito all’interno di una pagina HTML

La creazione di un APPLET differisce da quella di una applicazione perche’ gli applet devono essere presentati all’interno della pagina Web insieme agli altri elementi della pagina.

Un applet HelloWorld oltre a stampare il messaggio deve anche occuparsi di trovare lo spazio sulla pagina e di visualizzarlo in modalita’ grafica sullo schermo

La compilazione di un applet e’ identica a quella di una applicazione

Compilare normalmente il seguente file: CiaoATuttiApplet.java

Ogni applet deve essere visualizzato da un browser e chiamato all’interno di una pagina html

ESEMPIO:Generare il seguente file HTML e caricarlo con Netscape per visualizzare l’APPLET CiaoATuttiApplet.html

Il file .class e il file .html devono essere nella stessa directory

WIDTH=150 HEIGHT=25 servono al browser per determinare lo spazio da riservare all’applet nella pagina


EREDITARIETA’

TUTTE LE CLASSI SONO ORGANIZZATE IN UNA STRETTA GERARCHIA

OGNI CLASSE HA DELLE SUPERCLASSI (Classi Padre)

OGNI CLASSE PUO’ AVERE DELLE DELLE SOTTOCLASSI (classi figlio)

LE SOTTOCLASSI ERIDITANO ATTRIBUTI E COMPORTAMENTO (metodi) DALLE LORO SUPERCLASSI

UNA SPECIALIZZAZIONE COMPORTA LA CREAZIONE DI UNA NUOVA CLASSE CHE EREDITA DA UN’ALTRA CLASSE NELLA GERARCHIA

IN JAVA OGNI CLASSE DERIVA CLASSE OBJECT CHE IMPLEMENTA I METODI STANDARD DI UNA CLASSE

IN JAVA UNA CLASSE PUO’ AVERE SOLO UNA SUPERCLASSE (Ereditarietà Singola)

Nella realizzazione di un programma e’ necessario stabilire quali classi realizzare e definire come queste classi devono essere organizzate.

  • E’ NECESSARIO STABILIRE LA PROPRIA GERARCHIA:
  • LE PARTI COMUNI A PIU’ CLASSI POSSONO ESSERE INSERITE IN UNA SUPERCLASSE
  • LA MODIFICA DI UNA SUPERCLASSE SI RIPRODUCE AUTOMATICAMENTE A TUTTE LE SOTTOCLASSI (senza necessita’ di ricompilazione)
  • UNA SUPERCLASSE E’ UNA GENERALIZZAZIONE
  • UNA SOTTOCLASSE E’ UNA SPECIFICAZIONE


OVERLOADING

UNA SOTTOCLASSE PUO’ RIDEFINIRE UN METODO GIA’ IMPLEMENTATO IN UNA SUPERCLASSE (OVERLOADING)

Una sottoclasse puo’ contenere un metodo con lo stesso nome e stessi parametri di un metodo definito da una sua superclasse.

PER LA CLASSE, E TUTTE LE SUE SOTTOCLASSI, IL NUOVO METODO SI SOSTITUISCE A QUELLO DELLA SUPERCLASSE

nell’esempio precedente il metodo StampaAttributi era ridefinito in Motocicletta,Autocarro e Autoveicolo in modo da poter stampare anche gli attributi specifici delle classi relative.


INTERFACCE

UNA SUPERCLASSE PUO’ DEFINIRE UN METODO SENZA FORNIRNE L’IMPLEMENTAZIONE

DEFINIRE UNA INTERFACCIA SIGNIFICA DEFINIRE IL NOME ED I PARAMETRI DI UN METODO

L’IMPLEMENTAZIONE DI UN INTERFACCIA VA FATTA NELLE SOTTOCLASSI

SOTTOCLASSI DIVERSE POSSONO FORNIRE IMPLEMENTAZIONI TOTALMENTE DIVERSE PER L’INTERFACCIA EREDITATA DA UNA STESSA SUPERCLASSE

PER OGNI METODO POSSO AVERE PIU’ INTERFACCE CON PARAMETRI DIFFERENTI

ESEMPIO: La classe NumeroReale.java

ESEMPIO: La sottoclasse NumeroCplx.java


VARIABILI

UNA VARIABILE E’ UNA LOCAZIONE DI MEMORIA NELLA QUALE SI PUO’ MEMORIZZARE UN VALORE.

UNA VARIABILE HA UN NOME, UN TIPO ED UN VALORE.

IN JAVA ESISTONO:

  • VARIABILI DI ISTANZA: che sono gli attributi di una classe
  • VARIABILI DI CLASSE: che sono attributi costanti i cui valori si applicano a tutte le istanze della classe
  • VARIABILI LOCALI: che sono le variabili dichiarate ed utilizzate dai metodi

IN JAVA NON ESISTONO VARIABILI GLOBALI

LE INFORMAZIONI GLOBALI SONO GLI OGGETTI E SONO ACCESSIBILI SOLO TRAMITE I LORO METODI

DICHIARAZIONE DI VARIABILI

int x=0;
boolean acceso,verificato;
String nome="Andrea"

TIPI VARIABILI

uno dei tipi primitivi

byte    8bit   da -128   a 127
short   16bit  da -32768 a 32767
int     32bit  da -231    a 231-1
long    64bit  da -263    a 263-1

una classe

Pulsante mioPulsante = new Pulsante();

un array

String[] cognomi = new String[10];


Creazione di oggetti: new

L’OPERATORE new SI USA PER CREARE UN ISTANZA DI UNA CLASSE (un oggetto)

  • new ALLOCA LA MEMORIA PER L’OGGETTO DELLA CLASSE INDICATA
  • new CHIAMA IL COSTRUTTORE DELLA CLASSE PER INIZIALIZZARE GLI ATTRIBUTI

OGNI CLASSE HA UN COSTRUTTORE DI DEFAULT CHE CREA L’OGGETTO IN MEMORIA

OGNI CLASSE PUO’ A VERE PIU’ DI UN COSTRUTTORE

IL COSTRUTTORE DI UNA CLASSE E’ UN METODO SPECIALE DEFINITO NELLA CLASSE, HA IL SUO STESSO NOME E NON TORNA ALCUN VALORE

ESEMPIO: un costruttore per la classe NumeroCplx

public class NumeroCplx extends NumeroReale
{
  double img;
  NumeroCplx(){}
  NumeroCplx(double r, double i)
  { 
    this.real = r;
    this.ing  = i;
  }
  NumeroCplx(double r)
  {    this.real = r;   }
.....

//creo un oggetti di tipo NumeroCplx utilizzando differenti costruttori

NumeroCplx c1 = new NumeroCplx();
NumeroCplx c2 = new NumeroCplx(45.3,7);
NumeroCplx c3 = new NumeroCplx(12);


ARRAY

UN ARRAY E’ UN INSIEME ORDINATO E OMOGENEO DI OGGETTI.

OGNI ELEMENTO DI UN ARRAY CONTIENE UN OGGETTO O UN TIPO PRIMITIVO IN OGNI CASO TUTTI GLI ELEMENTI SONO DELLO STESSO TIPO

UN ARRAY E’ UN OGGETTO JAVA ED E’ UTILIZZABILE COME TUTTI GLI OGGETTI JAVA

DICHIARAZIONE DI ARRAY:

String[] cognomi = new String[10];
String cognomi[] = new String[10];    //dichiarazione analoga alla prec.

byte[][] bitmap = new byte[640][480];  //matrice: array multimensionale

ESEMPIO: ArrayTest.java

Prima che lastNames[i] vengano inizializzati il loro valore e’ null che si riferisce all’oggetto nullo predefinito in java

null non coincide con zero come la costante NULL del linguaggio C/C++


L’ISTRUZIONE switch

L’ISTRUZIONE switch E’ UNA ISTRUZIONE CONDIZIONALE ED ESEGUE UNA PARTE DI CODICE IN FUNZIONE DI UN TEST INIZIALE.

switch E’ L’ANALOGO DI CASE DEI LINGUAGGI TRADIZIONALI

switch ESEGUE TEST SOLO SU TIPI DI DATI PRIMITIVI (byte, char, short o int

ESEMPIO: uso di switch

class NumberReader
{
  String convertNum(int val) 
  {
    String s;
    switch (val) 
    {
      case 0: s= "zero ",break;
      case 1: s= "uno ",break;
      case 2: s= "due ",break;
      case 3: s= "tre ",break;
      case 4: s= "quattro ",break;
      case 5: s= "cinque ",break;
      case 6: s= "sei ",break;
      case 7: s= "sette ",break;
      case 8: s= "otto ",break;
      case 9: s= "nove ",break;
      default: s= " ";
    } //fine di switch
    return s;
  }

  public static void main (String args[]) 
  {
    NumberReader n = new NumberReader();

    String num = n.convertNum(4) + n.convertNum(1)  + n.convertNum(5);
    System.out.println("415 converts to " + num);
  }
}

dopo ogni case ci possono essere piu’ istruzioni. La parola chiave break termina il blocco per ogni case e porta il programma alla fine di switch


CICLI for

Il ciclo for ripete un istruzione o un blocchi di istruzioni, un numero prefissato di volte:

SINTASSI:

for(inizializzazione;condizione;incremento) 
{
  istruzioni
}

ESEMPIO: stampa degli elementi di un array

String[] firstNames = { "Dennis", "Grace", "Bjarne", "James" };
..
for(i=0;i<firstNames.length;i++)
{
  system.out.println(firstNames[i]);
}

CICLI do e while

Eseguono un’istruzione o un blocco di istruzioni fino a quando una condizione prefissata risulta vera.

SINTASSI:

while (condizione)
{
  istruzioni;
}
do
{
  istruzioni;
} while (condizione);

ESEMPIO: stampa degli elementi di un array

String[] firstNames = { "Dennis", "Grace", "Bjarne", "James" };
..
i=0;
do
{
 system.out.println(firstNames[i++]);
} while(i<firstNames.length);
i=0;
while(i<firstNames.length);
{
 system.out.println(firstNames[i++]);
}


MODIFICATORI

I MODIFICATORI SONO SPECIALI PAROLE CHIAVE CHE MODIFICANO LA DEFINIZIONE (E IL COMPORTAMENTO) DI UNA CLASSE, UN METOTO O UN ATTRIBUTO.

  • CONTROLLO DELL’ACCESSO : public,protected e private
  • CLASSI E METODI ASTRATTI: abstract
  • METODI E VARIABILI DI CLASSE: static
  • FINALIZZARE L'IMPLEMENTAZIONE DI UNA CLASSE: final
  • CREAZIONE DI METODI NATIVI: native
  • GESTIONE DEI THREAD: syncronized e volatile

per utilizzare un modificatore basta inserirlo prima delle definizioni

public class MioApplet extends java.applet.Applet {...}
private boolean statoMotore;
static final double pi = 3.14152965;
protected static final int MAXELEMENTI = 128
public static void main(String arg[]){...}

 e’ possibile utilizzare piu’ di un modificatore contemporaneamente

public, protected e private sono tra loro esclusivi l’ordine non e’ importante

tutti i modificatori sono opzionali, tuttavia e’ bene esplicitare l’utilizzo e le restrizioni sugli elementi dichiarati, utilizzando i modificatori.


CONTROLLO D’ACCESSO A METODI e VARIABILI

una classe e’ dotata di attributi e metodi necessaria al suo funzionamento. Ogni classe dipone di interfacce verso l’esterno per interagire con altri oggetti

l’accesso diretto agli atributi di una classe puo’ provocare inconsistenze nei dati della classe e sicuramente impedisce la modularita’ della classe stessa

OGNI PROGETTISTA DI UNA CLASSE O DI UNA GERARCHIA DEVE DEFINIRE LE INTERFACCE DELLA CLASSE SPECIFICANDO QUALI PARTI SONO ACCESSIBILI DA ALTRE CLASSI E QUALI DI USO INTERNO ALLA CLASSE

INCAPSULAMENTO: proceso con cui si nascondono le parti interne di una classe consentendo l’accesso alla classe solo attraverso interfacce predefinite

  • PUBLIC: un attributo o un metodo PUBLIC e’ accessibile a tutte le altre classi java. I metodi dichiariti public devono essere public anche nelle eventuali sottoclassi.
  • PROTECTED: un attributo o un metodo PROTECTED e’ accessibile a tutte le sottoclassi e le classi dello stesso package. I metodi dichiarati protected NON possono essere private nelle eventuali sottoclassi.
  • PRIVATE: un attributo o un metodo PUBLIC e’ accessibile solo ad altri metodi della stessa classe. I metodi private NON sono ereditati

METODI DI ACCESSO:

SONO METODI PUBLIC DI UNA CLASSE CHE DANNO L’ACCESSO IN LETTURA SCRITTURA AD ATTRIBUTI PRIVATI DELLA CLASSE

ESEMPIO: la classe cerchio

class Cerchio
{
  public static float PI=3.14159265F;
  private int x,y;
  private double raggio,area;

  Cerchio()                         // costruttore 1
  { x=y=0;
    setRaggio(0);  
  }

  Cerchio(int xc,int yc, double r)  // costruttore 2
  { x=xc;y=yc;
    setRaggio(r);
  }

  public double getRaggio()  {return raggio;}
  public double setRaggio(double r)
  {
    raggio =r;
    area = r * r * PI;
    return raggio;
  } //fine di setRaggio
  public void printData()  
  {
    System.out.println("-------------");
    System.out.println("Coordinate del centro(x,y): " + x + "," + y);
    System.out.println("Raggio: " + raggio);
    System.out.println("Area: " + area);
    System.out.println("-------------");

  } //fine di printData

  public static void main(String args[])  
  {
    Cerchio c1 = new Cerchio(100,50,0);
    c1.printData();
    c1.setRaggio(10);
    System.out.println("ora il cerchio ha raggio " + c1.getRaggio());
    c1.printData();

  } //fine di main
} //fine di Cerchio


PACKAGE

UN PACKAGE E’ UNO STRUMENTO PER RAGGRUPPARE LE CLASSI TRA LORO CORRELATE (per ereditarieta’ o per scopo)

  • Consentono di organizzare le classi in unita’ simili alle directory di un disco fisso, organizzano le classi in gruppo per utilizzare solo le quelle che servono
  • Riducono il conflitto tra i nomi delle classi
  • Un package puo’ contenere altri package formando una struttura gerarchica. Ogni livello e’ un gruppo di classi che opera con un compito specifico. La libreria di classi di java e’ un package che si chiama java e che dispone di altri sottopackage quali io, net, util, awt,...

USO di PACKAGE

Per accedere ad una classe contenuta in un package e’ necessario chiamarla con il suo nome e il percorso di package che la contiene

ESEMPIO: creo un oggetto f di tipo Font che e’ una classe del sottopackage awt del package java
java.awt.Font f = new java.awt.Font()

 Per classi utilizzate di frequente e’ possibile importare la classe o l’intero package all’interno della propria classe

ESEMPIO: importo la classe Vector che e’ una classe del sottopackage util del package java
import java.util.Vector

 

ESEMPIO: importo l’intero sottopackage (solo classi public) awt del package java

import java.awt.*

CREAZIONE di PACKAGE

 Un package se ben progettato e’ una estensione del linguaggio (o meglio della sua libreria)

Ogni package deve essere contenuto in una directory con lo stesso nome del package. Questa directory conterra’ tante sottodirectory quanti sono i sottopackage del package principale.

La radice della directory principale di un package deve essere una delle directory impostate con la variabile d’ambiente CLASSPATH

Per aggiungere una classe ad un package e’ necessario inserire all’inizio del file sorgente per la classe, il comando package nomepackage

 


AWT - Abstract Windowing ToolKit

UN PACKAGE PROGETTATO PER FACILITARE LA GESTIONE DI INTERFACCE UTENTE PER APPLET ED APPLICAZIONI JAVA.

AWT SI COMPONE DI

  • COMPONENTI PER L’INTERFACCIA UTENTE: finestre, pulsanti, menu, caselle di controllo, campi di testo, ...
  • SUPPORTO PER CONTENITORI PER ELEMENTI AWT: oggetti che possono contenere componenti per l’interfaccia o altri contenitori
  • GESTIONE DEGLI EVENTI DI SISTEMA PER IL CONTROLLO DELL’INTERAZIONE CON L’UTENTE
  • MECCANISMI PER LA PROGETTAZIONE DEL LAYOUT DELL’INTERFACCIA INDIPENDENTE DALLA PIATTAFORMA

OGNI PROGRAMMA GRAFICO E’ UNA COLLEZIONE DI COMPONENTI ORGANIZZATI IN MODO GERARCHICO A COMINCIARE DALLA FINESTRA PIU’ ESTERNA PER ARRIVARE ALLA PIU’ PICCOLA COMPONENTE DELL’APPLICAZIONE

OGNI ELEMENTO DELLA GERARCHIA PUO’ ESSERE UN ELEMENTO VISIBILE O UN CONTENITORE

LA GERARCHIA DEI COMPONENTI DETERMINA LA POSIZIONE SULLO SCHERMO E L’ORDINE CON CUI VENGONO DISEGNATE

 

estratto della gerarchia della classe java.awt


Component.Label

Stringa di testo utilizzabile per etichettare altre componenti. Non puo’ essere modificata dall’utente

COSTRUTTORI:

  • Label(): crea un’etichetta vuota con allineamento a sinistra
  • Label(String): crea un etichetta inizializzata con una stringa
  • Label(String,int): crea l’etichetta e inizializza il testo e l’allineamento

La classe label dispone di Label.RIGHT Label.CENTER e Label.LEFT che sono nomi mnemonici per i valori degli allineamenti

Il font dell’etichetta e’ controllabile con il metodo setFont() richiamato sulla etichetta o sul componente che la contiene (in questo caso cambiano i font di tutti gli elementi che contiene il componente)

Esempio: LabelTest.java

il metodo setFont imposta il font per tutto l’applet

il metodo add aggiunge l’oggetto all’applet


Component.Button

SEMPLICI COMPONENTI CHE AVVIANO UNA AZIONE QUANDO VENGONO PREMUTI

COSTRUTTORI:

  • Button(): Crea un pulsante vuoto (senza etichetta)
  • Button(String): crea un pulsante con etichetta con la stringa specificata

la classe fornisce anche i metodi

  • getLabel(): restituisce l’etichetta di un pulsante
  • setLabel(String): imposta l’etichetta per il pulsante

ESEMPIO:ButtonTest.html


Component.Checkbox

COMPONENTI DI INTERFACCIA A VALORE BOOLEANO. SERVONO AD INDICARE DELLE SCELTE TRA UN GRUPPO PREIMPOSTATO DI POSSIBILI OPZIONI.

Se solo una delle opzioni puo’ essere selezionata allora le checkbox sono ESCLUSIVE

COSTRUTTORI:

  • Checkbox(): crea una checkbox vuota e disattivata
  • Checkbox(String): crea una checkbox con una etichetta e disattivata
  • Checkbox(String,boolean): crea una checkbox con etichetta, disattivata o disativata in funzione del parametro boolen

per ottenere delle checkbox esclusive e’ necessario creare un gruppo di checkbox e far appartenere le singole checkbox allo stesso gruppo. In tal caso bisogna utilizzare il costruttore:

Checkbox(String,boolean,CheckboxGroup): crea una checkbox esclusiva sul gruppo indicato, con etichetta, disattivata o disativata in funzione del parametro boolen

siccome all’interno di uno stesso gruppo solo un checkbox puo’ essere attivo, l’ultimo pulsante con true aggiunto al gruppo e’ quello attivo per default

Altri metodi per la classe:

  • getLabel() : ritorna l’etichetta associata al pulsante
  • setLabel(String) : imposta l’etichetta per il pulsante
  • getState(): ritorna lo stato del pulsante
  • SetState(boolean): imposta lo stato del pulsante

ESEMPIO: CheckboxGroupTest.html


Component.Choice

COMPONENTI PER REALIZZARE ELENCHI A COMPARSA SU CUI EFFETTUARE UNA SCELTA

per creare un menu di scelta e’ necessario istanziare un oggetto della classe choice e successivamente aggiungere gli elementi

METODI DISPONIBILI

  • add(String): inserisce la stringa nell’elenco delle opzioni selezionabili
  • getItem(int): restituisce l’elemento alla posizione indicata (0=primo elem.)
  • getItemCount(): ritorna il numero degli elementi
  • getSelectedItem(): ritorna la stringa dell’elemento selezionato
  • getSelectedIndex(): ritorna l’indice dell’elemento selezionato
  • select(int|String): seleziona l’elemento speificato

 

ESEMPIO: ChoiceTest.html


Component.Text & Component.TextField

 CASELLE CHE CONSENTONO ALL’UTENTE L’INSERIMENTO DI TESTO

In sono costituite da una singola riga e non hanno barre di scorrimento. Per testi di maggiori dimensioni utlizzare TextArea

COSTRUTTORI:

  • TextField(): crea un campo di testo vuoto largo 0 caratteri. La dimensione viene poi impostata dal gestore del layout
  • TextField(int): crea un campo di testo vuoto largo n caratteri.
  • TextField(String): crea un campo di testo inizializzato con la stringa indicata
  • TextField(String,int): come sopra solo che vengono visualizzati solo i primi n caratteri (n e’ il valore del 2° parametro)

ALTRI METODI DELLA CLASSE:

  • getText(): ritorna il contenuto del campo
  • setText(): imposta il contenuto del campo
  • getColums(): ritorna la dimensione del campo testo
  • select(int,int): seleziona il testo compreso tra le posizioni indicate (0 primo carattere)
  • selectAll(): seleziona tutto il campo di testo
  • setEditable(boolean): con true il testo e’ modificabile dall’utente
  • getEditable(): ritorna true o false se il testo e’ modificabile o no
  • setEchoChar(char): imposta il carattere con cui il testo viene visualizzato sullo schermo
  • getEchoChar(): ritorna il carattere impostato con setEchoChar()
  • echoCharIsSet(): ritorna true o false a seconda se echoChar e’ stato impostato

 

ESEMPIO: TextFieldTest.html


PANNELLI E LAYOUT

UN PANNELLO PUO’ CONTENERE UNA INTERFACCIA UTENTE O ALTRI PANNELLI

LA DISPOSIZIONE DEI COMPONENTI DELL’INTERFACCIA UTENTE DEFINISCE L’ASPETTO DELL’INTERFACCIA UTENTE STESSA

POICHE’ L’APPLICAZIONE JAVA PUO’ ESSERE VISUALIZZATA SU DIVERSE PIATTAFORME E’ NECESSARIO DISPORRE DI UN METODO FLESSIBILE CHE RENDI L’ASPETTO DELL’INTERFACCIA, FUNZIONALE SULLE DIVERSE PIATTAFORME.

JAVA DISPONE DI GESTORI DI LAYOUT CHE CONSENTYO DI CREARE LA FINESTRA IN MODO DINAMICO

GESTORI DI LAYOUT

L’ASPETTO DELL’INTERFACCIA DIPENDONO DA

  • l’ordine con cui le componenti AWT vengono aggiunte al pannello
  • dal gestore di layout utilizzato

IL GESTORE DI LAYOUT DETERMINA IL MODO CON CUI LE COMPONENTI AWT VENGONO DISPOSTE DINAMICAMENTE SULLO SCHERMO

Ogni pannello puo’ contenere altri pannelli e ogni pannello puo’ disporre di un proprio gestore di layout.

AWT dispone 5 diversi gestori di layout: FLOW, GRID, GRIDBAG,BORDER E CARD

FlowLayout

LE COMPONENTI VENGONO AGGIUNTE UNA ALLA VOLTA PER RIGA

Se una componente non ci sta in una riga viene portata alla riga successiva

Per default le righe sono allineate al centro del pannello

ESEMPIO: imposto un FlowLayout con allineamento a sinistra spaziatura di 30 pixel tra gli elementi e 10 pixel tra le righe

setLayout(new FlowLayout(FlowLayout.LEFT,30,10);

GridLayout

CON IL LAYOUT A GRIGLIA IL PANNELLO E’ SUDDIVISO IN RIGHE E COLONNE ED OGNI COMPONENTE VIENE AGGIUNTO IN UNA CELLA DELLA GRIGLIA.

Il primo elemento aggiunto al pannello viene posizionato nella cella in alto a sinistra

Gli elementi successivi vengono posizionati da sinistra verso destra e dall’alto in basso

PER CREARE UN LAYOUT A GRIGLIA E’ NECESSARIO DEFINIRE IL NUMERO DI RIGHE E DI COLONNE.

ESEMPIO:layout a griglia con tre righe e due colonne con una spaziatura tra le colonne di 30 pixel e 10 pixel di spaziatura tra le righe

setLayout(new GridLayout(3,2,30,10);

BorderLayout

CON IL LAYOUT A BORDI IL PANNELLO VIENE SUDDIVISO IN 5 ZONE: North, South, West, East, Center

con questo gestore e’ necessario indicare al metodo add in quale zona posizionare il componente

Le componenti ai bordi vengono greati con la dimensione necessaria mentre il componente al centro se esiste occupa tutto lo spazio rimanente

public class BorderLayoutTest extends java.applet.Applet {
  public void init() {
    setLayout(new BorderLayout());
    add("North", new Button("One"));
    add("East", new Button("Two"));
    add("South", new Button("Three"));
    add("West", new Button("Four"));
    add("Center", new Button("Five"));
  }
}

 

GridBagLayout

GridBagLayout gestisce il pannello con una griglia. Permette inoltre di specificare delle proprieta’ per le singole celle quali:

  • occupazione del componente rispetto alla cella (fill)
  • la posizione del componente all’interno della cella (anchor)
  • proporzioni della cella rispetto alle celle della stessa riga (weithtx) e della stesa colonna (weithty)
  • numero di celle su cui si estente il componente lungo le righe (gridwidth) e lungo le colonne (gridheight)

 IL GESTORE SI COMPONE DI DUE CLASSI:

  • GridBagLayout: fornisce il gestore di layout
  • GridBagConstraints: che definisce le proprieta’ di ogni componente della griglia

SINTETICAMENTE LA CREAZIONE DI UN GridBagLayout RICHIEDE I SEGUENTI PASSI

  1. Creazione dell’oggetto GridBagLayout
  2. Creazione dell’oggetto GridBagConstraints
  3. Definizione di un set di proprieta’
  4. Associazione delle proprieta’ al componente
  5. Aggiunta del componente al gestore del layout

ESEMPIO: GridBagTestFinal.html


Pannelli annidati

LA CLASSE Applet E’ UNA SOTTOCLASSE DI Panel

Per annidare altri pannelli all’interno di un applet e’ sufficiente creare un nuovo pannello ed aggiungerlo all’applet

SetLayout(new GridLayout(1,2,10,10)
Panel pane1A = new Panel();
Panel pane1B = new Panel();
add(panelA);
add(panelB);

Ogni Panel puo’ avere un gestore di layout e componenti indipendenti

PanelA.setLayout(new FlowLayout());
panelA.add(new Button("UP");
panelA.add(new Button("DOWN");


Gestione di eventi dell’interfaccia utente (Java 1.02)

I COMPONENTI DELL’INTERFACCIA UTENTE SONO COMPONENTI "STATICI" PERCHE’ DA SOLI NON GENERANO ALCUNA AZIONE VERSO L’APPLICAZIONE

OGNI COMPONENTE GENERA UN EVENTO NEL MOMENTO IN CUI L’UTENTE COMPIE UNA AZIONE SUL COMPONENTE STESSO

L’APPLICAZIONE DEVE GESTIRE GLI EVENTI GENERATI DALLE COMPONENTI IMPLEMENTANDO UNA "AZIONE CONCRETA" IN RISPOSTA AL’INPUT DELL’UTENTE

Tranne le componenti Label, tutti i componenti AWT generano eventi

  • DI AZIONE: sono eventi principali. Indicano che il componente e’ stato attivato. Pressione di un pulsante, attivazione di una casella di controllo, selezione di un menu di scelta, pressione del tasto invio su una casella di testo,…
  • DI SELEZIONE E DESELEZIONE IN UN ELENCO: eventi generati quando si seleziona una casella di controllo o una voce in un menu di scelta (viene generato anche un evento di azione)
  • DI SELEZIONE E DESELEZIONE PER L’INPUT: indicano che il componente e’ stato scelto. Vengono generati da tutti i componenti (tranne Label) quando viene premuto il tasto Tab o con un click del mouse


Eventi di azione

Per la gestione degli eventi di azione esiste il metodo specifico action

Public boolean action(Event evt, Object arg)

IL SISTEMA DI GESTIONE DELGLI EVENTI DI JAVA CHIAMA AUTOMATICAMENTE IL METODO ACTION QUANDO SI VERIFICA UN EVENTO DI AZIONE

IL METODO ACTION VA RISCRITTO NELLA CLASSE UTENTE IN MODO DA COMPIERE L’AZIONE DESIDERATA IN RISPOSTA AL COMPONENTE DELL’INTERFACCIA CHE HA GENERATO L’EVENTO

Il parametro arg e’ un parametro il cui tipo dipende dal componente AWT che ha generato l’evento, per un pulsante ad esempio e’ l’etichetta del pulsante

Il primo parametro di action e’ l’oggetto event che e’ stato generato.

Tale oggetto porta con se delle informazioni tra cui l’oggetto che ha ricevuto l’evento. Questa informazione e’ utilizzata per scrivere l’implementazione dell’azione associata all’oggetto

ESEMPIO:

Public boolean action(Event evt, Object arg)
{
  if(evt.target istanceof TexField) return GestisciTesto(evt.Target);
  else if(evt.target istanceof Choice) return GestisciScelta(evt.Target);
  else if(evt.target istanceof Button) return GestisciPulsante(arg);
  else if ...
  return false;
}

Public boolean GestisciPulsante(String label)
{
  if(label.equals("OK") return GestisciOK();
  else if ...
}

Eventi di selezione e deselezione

  • SELEZIONE PER L’INPUT: in questo caso sono disponibili i metodi
public boolean gotFocus(Event evt, Object arg);
public boolean lostFocus(Event evt, Object arg);

Questi metodi vengono chiamati dal gestore del layout ogni volta che si preme il tasto Tab o viene clickato uno dei componenti del’interfaccia

  • SELEZIONE DA UN ELENCO: in questo caso non esistono dei gestori specifici quindi si utilizza il metodo generico handleEvent
public boolean handleEvent(Event evt)
{
  if(evt.id == Event.LIST_SELECT) GestisciSelezione(Event);
  else if(evt.id == Event.LIST_DESELECT) GestisciDeselezione(Event);
  else return super.handleEvent(evt) //passa al gestore standard
}

tutti i gestori devono ritornare true o false in funzione se l’evento e’ stato "consumato" o meno

ESEMPIO: ButtonActionsTest.html


JDBC API (Application Program Interface)

JDBC API non permettono la gestione diretta di un database, ma solo l'invio di istruzioni in un linguaggio standard (SQL), e la manipolazione degli eventuali risultati.

Molto sinteticamente i passi necessari da compiere sono i seguenti:

  • Conessione al database - Creazione di un oggetto Connection
  • Creazione ed invio di istruzioni SQL al DB per mezzo delle classi Statement
  • PreparedStatement e CallableStatement.
  • Esecuzione delle query
  • Elaborazioni dei risultati
  • Chiusura della connessione

Modello a due strati


Organizzazione delle JDBC API

DRIVER LAYER: livello orientato al database. Interagisce col database attraverso chiamate a basso livello verso le tabelle dello stesso

APPLICATION LAYER: livello orientato all’applicazione

Il colloquio fra i due livelli è reso possibile rispettando le specifiche delle API ed utilizzando in pratica la classe Driver.

Principalmente questa parte di codice è cositituita da quattro interfaccie che ogni driver deve implementare per mantenere la compatibilità con le direttive JDBC, più la classe Driver; le 4 interfaccie sono Driver, Connection, Statement, e ResultSet.

Driver Layer

Questa parte delle API si suddivide in due interfaccie (classi):

  • Driver: è strettamente legata al concetto di database vero e proprio. Nell'ambito dell'applicazione, rappresenta l'astrazione del database a cui si e’ connessi.
  • DriverManager: si preoccupa di caricare e scaricare a run time, i singoli driver, di eseguire la connessione coi singoli driver, e di fornire i vari servizi per il login e logout ai db.

La classe Driver

Questa classe permette la connessione ad una base di dati a partire da una stringa di connessione La stringa di connessione ha una sintassi molto simile a quella utilizzata per gli URL usati dal sistema World wide Web:

jdbc:<subprotocol:<subname

dove <subprotocol definisce il tipo del driver, mentre <subname definisce il nome del db codificato secondo le specifiche del sistema.

ESEMPIO:

jdbc:odbc:biblio

definisce un driver per odbc e un db denominato biblio.

La parte dedicata al subaname può inglobare informazioni più specifiche relativamente al dabase, come il path assoluto, la porta di accesso al server, l'account e la password, in maniera del tutto analoga a come avviene ad esempio nella definizione di un URL di una pagina WEB. Ad esempio possiamo quindi avere

jdbc:msq1://mokabyte.programmers.net.+puliti+.+password+:1112/mokadb

dove si é specificato il server sul quale risiede il db, la UID e password, la porta ed infine il path del db relativamente alla macchina specificata.

La classe Driver e’ di fornisce i suoi servizi alla classe DriverManager che e’ di fatto la classe con la quale si andra’ ad interagire

La classe DriverManager

Questa classe fornisce i metodi fondamentali per:

  • la connessione a database,
  • per settare i parametri di login-logout
  • per registrare e deregistrare i vari driver

Tutti i metodi della classe sono statici per cui possono essere invocati anche senza instanziare la classe di riferimento che comunque è la java.sql.DriverManager

public static synchronized Connection getConnection(String url, Properties prop) throws SQLException

Questo metodo, tenta una connessione restituendo un oggetto Connection. Durante la fase di apertura della connessione viene scorsa una lista di driver ed il primo che permette la connessione viene scelto. La lista dei driver viene conservata in un oggetto di tipo Vector.

Per caricare un driver al DriverManager si puo’ eseguire una chiamata metodo Class.forName, il quale esplicitamente carica la classe driver in questione e la aggiunge alla lista

ESEMPIO: supponendo di voler caricare un driver denominato MBPkgs.drivers.MBdriver1, allora possiamo scrivere

Class.forName("MBPkgs.drivers.MBdriver1");

L'Application Layer

Anche a questo livello ci sono tre interfaccie: Connection, Statement ,ResultSet

Per default, al momento della creazione, una Connection JDBC si trova impostata in autocommit mode, per cui le modifiche vengono eseguite automaticamente dopo ogni transazione.

E' possibile modificare tale proprietà passando come parametro false al metodo setAutoCommit(boolean b).

Nel caso in cui sia disabilitata la modalità di autocommit, ha senso utilizzare i metodi Connection.commit() e Connection.rollback(), per controllare meglio il flusso dei dati.

Alcuni dei metodi più importanti della interfaccia Connection

public abstract Statement createStatement() throws SQLException 
public abstract PreparedStatement prepareStatement(String sql) throws SQLException 
public abstract CallableStatement prepareCall(String sql) throws SQLException 

Questi tre metodi permettono di creare statements, cioé istruzioni da inviare al dbms, sia per eseguire operazioni sui dati, sia più semplicemente per estrarre informazioni.

Vi sono poi i metodi per la gestione del flusso di informazioni

    public abstract void commit() throws SQLException 
    public abstract void rollback() throws SQLException 

Statements 

La classe Statements permette la manipolazione di un database attraverso istruzioni in linguaggio SQL inviate al DBMS che penserà a processare tali comandi ed a restituire i risultati.

    public abstract ResultSet executeQuery(String sql) throws SQLException 

Esegue una semplice istruzione SQL passata in input e resituisce il recordset dei risultati sotto forma di un oggetto della classe ResultSet.

    public abstract int executeUpdate(String sql) throws SQLException 

Esegue un update secondo quanto scritto nella stringa SQL passata; non restuisce nessun set di risultati, ma solo il numero di righe (record) affetti da cambiamento.

public abstract ResultSet getResultSet() throws SQLException

Dopo aver eseguito una operazione sul db è possibile leggere il buffer contenente i risultati.

public abstract int getUpdateCount() throws SQLException

Restituisce lo stato di una operazione di aggiornamento update,insert, delete. Il valore resitituito è il mumero di righe che hanno subito il cambiamento, o -1 se non è disponibile nessun update count o se è stata eseguita precedentemente una operazione di update che non restituisce un update count ma un recordset.

L'interfaccia PreparedStatement deriva da Statement e offre una serie di meccanismi preparati nel caso in cui si debbano eseguire una serie di operazioni ripetitive.

La differenza fra uno statement ed uno prepared, è che quest'ultimo utilizza istruzioni SQL precompilate in cui si ha la possibilità di lasciare alcuni parametri generici e di settarli al momento della chiamata attraverso i metodi setType()

L'interfaccia ResultSet

definisce i metodi per accedere ai dati ottenuti come risultato dall'esecuzione di uno statement. I valori relativi ai vari campi possono essere ricavati sia facendo riferimento al nome del campo sia al suo indice (la numerazione parte da 1).

Metodi principali:

  • next():per passare al risultato successivo
  • getMetaData():restituisce un oggetto di tipo ResultSetMetaData(), col quale possiamo ricavare una serie di informazioni basilari sulla struttura del recordset ottenuto, come ad esempio il numero di colonne, il tipo di ogni colonna e altro ancora.

Caricamento del driver

La classe DriverManager che si occupa di tale operazione andando a scorrere la lista jdbc.drivers ed utilizzando il primo driver che risponde ai requisiti necessari.

E' possibile consultare tale lista per mezzo del metodo getDrivers().

La classe DriverManager non è l'unica che permette la connessione con un DB, ma è possibile utilizzare anche l'interfaccia Driver che permette di accedere a tutte le informazioni che riguardano il db, come ad esempio se esso è JDBC-Compliant, la versione, o se accetta un determinato URL.

 ESEMPIO-Collegamento ad un database biblio:

//caricamento del driver per dichiazione esplicita
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");  

//controllo del caricamento
try
{            
  Connection connessione=DriverManager.getConnection("jdbc:odbc:biblio");
  Enumeration enum = DriverManager.getDrivers();
  System.out.println("Driver ="+enum.nextElement());
  while  (enum.hasMoreElements())
  System.out.println("Driver"+enum.nextElement());
}
//sezione di gestione delle eccezioni
catch(SQLException sqle)
{

	System.out.println("ERRORE SQL "+sqle.toString());
	SQLException s=sqle.getNextException();
	while (s!=null)
  {
		System.out.println(s.toString());
		s=sqle.getNextException();
  }
}

Per poter eseguire istruzioni SQL le JDBC API mettono a disposizione tre metodi

boolean execute() 
ResultSet executeQuery() 
int executeUpdate(String sql)

Il metodo execute()è il più generico: permette di eseguire una qualsiasi operazione SQL.

Resituisce valori di tipo booleano che indicano se la query ha prodotto oppure no ResultSet, disponibili poi per mezzo della getResultSet().

Se non si sono prodotti recordset in uscita, (come nel caso di modifiche su una tabella), col metodo GetUpdateCount() si ottiene il numero di righe influenzate dalla modifica. Se il risultato di tale metodo è -1 significa che l'operazione eseguita non ha modificato nessun valore in tabella.

ESEMPIO: modifica ad alcuni record

//  Esempio di execute() di una Statement senza ResultSet: SELECT SQL
try{
   DriverManager.setLogStream(null);
   Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
   connessione=DriverManager.getConnection("jdbc:odbc:biblio");
   connessione.setAutoCommit(false);
   Statement st= connessione.createStatement();
   sql="SELECT name  FROM Authors";        
   risult = st.execute(sql);
   numris=st.getUpdateCount();
   connessione.rollback();

   // execute()  di una Statement con ResultSet:  UPDATE SQL
   sql = "UPDATE Authors SET Name = \'Pippo\' WHERE Name=\'Topolino\'";
   ResultSet rs =  st.getResultSet()
   risult = st.execute(sql);
   numris = st.getUpdateCount();
}
//sezione di gestione delle eccezioni

 ESEMPIO:creazione di una tabella inviando una stringa SQL con execute()

//  utilizzo di execute di una Statement senza ResultSet:        *
//  Creazione di una tabella
try
{
  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
  connessione=DriverManager.getConnection("jdbc:odbc:biblio");
  Statement st= connessione.createStatement();
  sql="CREATE TABLE tabella ( nome CHAR(100), anni Integer )";
  risult=st.execute(sql);
  numris=st.getUpdateCount();
}
//sezione di gestione delle eccezioni
catch(SQLException sqle)
{ 
  System.out.println("ERRORE SQL "+sqle.toString());
  SQLException s=sqle.getNextException();
  while (s!=null)
  {
    System.out.println(s.toString());
    s=sqle.getNextException();                      
  }
}

 Il metodo executeQuery() permette semplicemente l'esecuzione di una istruzione SQL rappresentata dal suo argomento di tipo stringa. Restituisce un valore singolo di tipo ResultSet. L'uso di tale metodo e’ del tutto equivalente al metodo execute().

Il metodo executeUpdate() permette di innoltrare istruzioni SQL del tipo DELETE UPDATE o INSERT che effettuano operazioni sui dati in modo da modificarne i valori.

Il valore restituito è il numero di record modificati dalla istruzione inviata: esso corrisponde al valore ottenibile per mezzo del getUpdateCount() dopo l'esecuzione di execute(). Non permette di eseguire istruzioni con risposte multiple.

Esempio di executeUpdate di una Statement. 

try{
	DriverManager.setLogStream(null);
	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
	connessione=DriverManager.getConnection("jdbc:odbc:biblio");
	connessione.setAutoCommit(false);
	Statement st= connessione.createStatement();
	String sql="UPDATE Authors SET Name = \'Topolino\' WHERE age < 30";
	numris = st.executeUpdate(sql);
	numris2=st.getUpdateCount();
	risult = st.getResultSet();
	connessione.rollback();
}

//sezione di gestione delle eccezioni
catch(SQLException sqle)
{
	System.out.println("ERRORE SQL "+sqle.toString());
	SQLException s=sqle.getNextException();
	while (s!=null){
		System.out.println(s.toString());
		s=sqle.getNextException();
	}

ESEMPIO: mySimpleSelect.java


Il PKLAB aderisce ai principi Open Access della Dichiarazione di Berlino (Sito italiano)
[Home Page]  [System Control]   [Robotic & Image processing]   [Applicazioni Speciali]  [Didattica]   [Networking]   [Search]

Contatto:
Valid CSS!