Listati estratti da Introduzione a Java, Andrea Guidi, Marco Bertacca, McGraw-Hill, ottobre 1997, ISBN 88-386-0764-8. Capitolo 1 - Introduzione al linguaggio class IlProgramma { // linea 1 public static void main (String argv[]) { // linea 2 System.out.println ("Il primo programma"); // linea 3 } // linea 4 } // linea 5 class AreaRettangolo { public static void main (String argv[]) { int base; int altezza; int area; base = 3; altezza = 7; area = base * altezza; System.out.println ("Area = "); System.out.println (area); } } class IlProgramma { public static void main (String argv[]) { int base; int altezza; int area; base = 3; altezza = 7; area = base * altezza; System .out.println("Area = "); System . out . println ( area ) ; } } class TavolaPitagorica { public static void main (String argv[]) { int tavolaPitagorica[][] = { { 0*0, 0*1, 0*2, 0*3 }, { 1*0, 1*1, 1*2, 1*3 }, { 2*0, 2*1, 2*2, 2*3 } }; System.out.println (tavolaPitagorica.length); System.out.println (tavolaPitagorica[0].length); System.out.println (tavolaPitagorica[2][3]); } } Capitolo 2 - Strutture di controllo decisionali 2.1 L'istruzione if if (i < 100) System.out.println ("minore di 100"); if (valore-booleano) istruzione1 [ else istruzione2 ]; if (i < 100) System.out.println ("minore di 100"); else System.out.println ("maggiore o uguale a 100"); 2.2 Blocchi if (i < 100) System.out.println ("minore di 100"); System.out.println ("istruzione successiva"); if (i < 100) System.out.println ("minore di 100"); System.out.println ("istruzione successiva"); if (i < 100) System.out.println ("minore di 100"); else System.out.println ("maggiore o uguale a 100"); System.out.println ("istruzione successiva alla clausola else"); boolean min100; if (i < 100) { System.out.println ("minore di 100"); min100 = true; } else { System.out.println ("maggiore o uguale a 100"); min100 = false; } boolean min100; if (i < 100) { System.out.println ("minore di 100"); min100 = true; } else System.out.println ("maggiore o uguale a 100"); min100 = false; 2.3 if annidati if (i < 100) if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); if (i < 100) if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); else System.out.println ("minore o uguale a zero"); if (i < 100) { if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); } else System.out.println ("maggiore o uguale a 100"); if (i < 100) if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); else System.out.println ("minore o uguale a zero "); else System.out.println ("maggiore o uguale a 100"); if (i < 100) if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); else System.out.println ("minore o uguale a zero "); else if (i == 100) System.out.println ("uguale a 100"); else System.out.println ("maggiore di 100"); if (i < 100) if (i > 0) System.out.println ("minore di 100 e maggiore di zero"); else if (i == 0) System.out.println ("uguale a zero"); else System.out.println ("minore di zero "); else if (i == 100) System.out.println ("uguale a 100"); else System.out.println ("maggiore di 100"); 2.5 Istruzione switch if (valore-booleano) istruzione1 else if (valore-booleano) istruzione2 else if (valore-booleano) istruzione3 ... else istruzioneN; switch (espressione) { case costante1: [istruzioni1;] [break;] case costante2: [istruzioni2;] [break;] case costante3: [istruzioni3;] [break;] ... case costanteN: [istruzioniN;] [break;] [default: [istruzioniDefault;] [break;]] } switch (x) { case 1: //Va al successivo case 2: //Va al successivo case 3: //Va al successivo case 5: //Va al successivo case 7: System.out.print (x); System.out.println (" Š un numero primo"); break; case 4: //Va al successivo case 6: //Va al successivo case 8: //Va al successivo case 9: //Va al successivo case 10: System.out.print (x); System.out.println (" non Š numero primo"); break; default: System.out.println ("x Š minore di 1 o maggiore di 10"); break; } Capitolo 3 - Strutture di controllo iterative 3.1 Istruzione while while (valore-booleano) istruzione; int x = 0; while (x < 30) x = x + 7; int x = -7; while ((x = x + 7) < 30) ; class Fattoriale1 { public static void main (String argv[]) { int n = 5; int fat = 1; int i = n; while (i > 1) { fat = fat * i; i = i - 1; } System.out.print ("Il fattoriale di "); System.out.print (n); System.out.print (" Š "); System.out.println (fat); } } 3.2 Istruzione do-while do istruzione while (valore-booleano); int n = 123456; do { System.out.print (n % 10); n = n / 10; } while (n > 0); System.out.println (""); class Fattoriale2 { public static void main (String argv[]) { int n = 5; int fat = 1; int i = 1; do { fat = fat * i; i = i + 1; } while (i <= n); System.out.print ("Il fattoriale di "); System.out.print (n); System.out.print (" Š "); System.out.println (fat); } } 3.3 Istruzione for for (inizializzazione; valore-booleano; incremento) istruzione; for (x = 1; x <= 10; x = x + 1) System.out.println (x); for ( ; x <= 10; ) while (x <= 10) for (int x = 1; x <= 10; x = x + 1) System.out.println (x); System.out.println (x); // Errore in compilazione ! class RovesciaParole { public static void main (String argv[]) { char parola[] = { 'p', 'r', 'o', 'v', 'a' }; int i1, i2; for (i1 = 0, i2 = parola.length - 1; i1 < i2; i1 = i1 + 1, i2 = i2 - 1) { char c = parola[i1]; parola[i1] = parola[i2]; parola[i2] = c; } System.out.println (parola); } } for (int i1 = 0, i2 = parola.length - 1; i1 < i2; i1 = i1 + 1, i2 = i2 - 1) { class Fattoriale3 { public static void main (String argv[]) { int n = 5; int fat; int i; for (i = n, fat = 1; i > 1; i = i - 1) fat = fat * i; System.out.print ("Il fattoriale di "); System.out.print (n); System.out.print (" Š "); System.out.println (fat); } } 3.4 Cicli annidati int altezza = 12, larghezza = 40; for (int i = 0; i < altezza; i++) { for (int j = 0; j < larghezza; j++) System.out.print("+"); System.out.println(""); } 3.5 Incrementi e decrementi int a, b, c; a = 5; b = 7; c = ++a + b; System.out.println (a); System.out.println (b); System.out.println (c); int a, b, c; a = 5; b = 7; c = a++ + b; System.out.println (a); System.out.println (b); System.out.println (c); for (x = 1; x <= 3; ++x) for (x = 1; x <= 3; x++) for (x = 1; ++x <= 3; ) for (x = 1; x++ <= 3; ) System.out.println ("++x"); for (int x = 1; ++x <= 3; ) System.out.println (x); System.out.println ("x++"); for (int x = 1; x++ <= 3; ) System.out.println (x); 3.6 Istruzioni break e continue char a[] = { 'a', 'b', 'c' } ; if (a.length > 0) for (int x = 0; ; ) { System.out.print (a[x]); if (++x < a.length) System.out.print (", "); else break; } System.out.println (""); char a[] = { 'a', 'b', 'c' }; for (int x = 0; x < a.length; ) { System.out.print (a[x]); if (++x < a.length) System.out.print (", "); } System.out.println (""); int ai[] = { 10, -10, 5, -5, 7, -7 } ; int somma = 0; for (int x = 0; x < ai.length; x++) { if (ai[x] <= 0) continue; somma += ai[x]; } System.out.println (somma); char a[] = { 'a', 'b', 'c', '?' , 'd', 'e', 'f'}; interruzione: for (int x = 0; x < a.length; x++) { switch (a[x]) { case '.': case ',': case ';': case ':': case '!': case '?': break interruzione; default: break; } System.out.println (a[x]); } System.out.println ("fine"); char a[] = { 'a', 'b', 'c', '?' , 'd', 'e', 'f'}; for (int x = 0; x < a.length; x++) interruzione: { switch (a[x]) { case '.': case ',': case ';': case ':': case '!': case '?': break interruzione; default: break; } System.out.println (a[x]); } System.out.println ("fine"); int altezza = 12; esterno: for (int i = 0; i < altezza; i++) { for (int j = 0; j < altezza; j++) { System.out.print("+"); if (j >= i) { System.out.println(""); continue esterno; } } } Capitolo 4 - I metodi class MetodoCubo { public static void main (String argv[]) { float a = 3; double b; float f; b = cubo (a); // linea 7 System.out.print (a); System.out.print (" elevato al cubo e' "); System.out.println (b); // linea 10 f = cubo (a); // linea 11 System.out.print (a); System.out.print (" elevato al cubo e' "); System.out.println (f); // linea 14 } static double cubo (float c) { // linea 16 return c * c * c; } static double cubo (double c) { // linea 19 return c * c * c; } } 4.3 Visibilit… static void g (int y, char z) { int k; int i; ... } static void f () { int x = 1; { int x = 2; // Errore!! System.out.println (x); } System.out.println (x); } static void g () { { int x = 2; } System.out.println (x); // Errore!! } static void g (x) { if (x == 2) return; System.out.println (x); } static double cubo (float c) { if (c != 3) return c * c * c; } // Errore !! static double cubo (float c) { if (c != 3) return c * c * c; else return 0; } static int cubo (float c) { return c * c * c; // Errore!! } static int cubo (float c) { return (int)(c * c * c); } 4.4 Un metodo utile class Input { public static void main (String argv[]) { int inp = 0; do { inp = leggi(true); System.out.print ("hai inserito "); System.out.println (inp); } while (inp != 0); do { inp = leggi(false); System.out.print ("hai inserito "); System.out.println ((char)inp); } while (inp != 0); } static int leggi(boolean num) { byte b[] = new byte[9]; int Return = 0; try { System.in.read(b); } catch (Exception e) { } if (num) for (int i = 0; i < b.length; i++) if (b[i] >= '0' && b[i] <= '9') Return = Return * 10 + b[i] - '0'; else break; else if (b[0] >= ' ') Return = b[0]; return Return; } } 4.5 Invocazione di un metodo class Input { public static void main (String argv[]) { float b, h; double a; char p; System.out.print ("Inserire poligono (T)riangolo/(R)ettangolo : "); p = (char)leggi (false); System.out.print ("Inserire base : "); b = leggi (true); System.out.print ("Inserire altezza : "); h = leggi (true); a = area (b, h, p); System.out.print ("Il poligono ha l'area = "); System.out.println (a); } static double area (float base, float altezza, char poligono) { switch (poligono) { case 'T': return base * altezza / 2.0; case 'R': return base * altezza; default: return 0; } } static int leggi(boolean num) { byte b[] = new byte[9]; int Return = 0; try { System.in.read(b); } catch (Exception e) { } if (num) for (int i = 0; i < b.length; i++) if (b[i] >= '0' && b[i] <= '9') Return = Return * 10 + b[i] - '0'; else break; else if (b[0] >= ' ') Return = b[0]; return Return; } } 4.6 Passaggio dei parametri class Parametri1 { public static void main (String argv[]) { double d = 30; f (d); System.out.println (d); } static void f (double d) { d = 0; } } class Parametri2 { public static void main (String argv[]) { double d[] = new double[1]; d[0] = 30; f (d); System.out.println (d[0]); } static void f (double d[]) { d[0] = 0; } } 4.7 Metodi ricorsivi class Fattoriale4 { public static void main (String argv[]) { int n = 15; System.out.print ("Il fattoriale di "); System.out.print (n); System.out.print (" Š "); System.out.println (fattoriale (n)); } static int fattoriale (int x) { if (x <= 1) return 1; else return x * fattoriale(x - 1); } } Capitolo 5 - Verso la programmazione a oggetti struct Tempo aggiungiOre (struct Tempo mioTempo, int numOre) { mioTempo.ore = mioTempo.ore + numOre; while (mioTempo.ore > 23) mioTempo.ore = mioTempo.ore - 24; return mioTempo; } 5.3 Programmazione a maniglie int newTempo () { int i; for (i = 0; i < DIM_ARRAY_TEMPO; i++) if (ArrayTempo[i].ore == 99) { ArrayTempo[i].ore = 0; ArrayTempo[i].minuti = 0; ArrayTempo[i].secondi = 0; return i; } return -1; } int assegnaTempo (int handle, int ora, int minuti, int secondi) { if (ora >= 0 && ora < 24 && minuto >= 0 && minuto < 60 && secondo >= 0 && secondo < 60) { ArrayTempo[handle].ore = ora; ArrayTempo[handle].minuti = minuto; ArrayTempo[handle].secondi = secondo; return 0; } else return -1; } int leggiOra (int handle) { return ArrayTempo[handle].ore; } int leggiMinuti (int handle) { return ArrayTempo[handle].minuti; } int leggiSecondi (int handle) { return ArrayTempo[handle].secondi; } La funzione che abbiamo gi… visto per aggiungere le ore diverrebbe quindi: void aggiungiOre (int handle, int numOre) { ArrayTempo[handle].ore = ArrayTempo[handle].ore + numOre; while (ArrayTempo[handle].ore > 23) ArrayTempo[handle].ore = ArrayTempo[handle].ore - 24; } Capitolo 6 - Le classi in Java class Tempo { private int ore; private int minuti; private int secondi; public char separatore; public int assegnaTempo (int ora, int minuto, int secondo) { if (ora >= 0 && ora < 24 && minuto >= 0 && minuto < 60 && secondo >= 0 && secondo < 60) { ore = ora; minuti = minuto; secondi = secondo; return 0; } else return -1; } public int leggiOra () { return ore; } public int leggiMinuti () { return minuti; } public int leggiSecondi () { return secondi; } public void aggiungiOre (int numOre) { ore = ore + numOre; while (ore > 23) ore = ore - 24; } public void visualizza (boolean ritornoACapo) { System.out.print (ore); System.out.print (separatore); System.out.print (minuti); System.out.print (separatore); if (ritornoACapo) System.out.println (secondi); else System.out.print (secondi); } } public void aggiungiOre (int numOre) { this.ore = this.ore + numOre; while (this.ore > 23) this.ore = this.ore - 24; } class ProvaTempo1{ public static void main (String argv[]) { Tempo mioTempo; mioTempo = new Tempo(); mioTempo.separatore = ':'; mioTempo.assegnaTempo(22,30,5); mioTempo.visualizza(true); mioTempo.aggiungiOre (10); mioTempo.visualizza(true); } } 6.3 Ereditariet… class Tempo2 extends Tempo { private int centesimi; public void assegnaCentesimi (int cent) { centesimi = cent; } public int leggiCentesimi () { return centesimi; } } 6.4 Polimorfismo public void assegnaTempo (Tempo t) { ore = t.ore; minuti = t.minuti; secondi = t.secondi; } public void assegnaTempo (int ora, int minuto, int secondo, int cent) { assegnaTempo (ora, minuto, secondo); centesimi = cent; } 6.5 Overriding public void visualizza (boolean ritornoACapo) { System.out.print (ore); System.out.print (separatore); System.out.print (minuti); System.out.print (separatore); System.out.print (secondi); System.out.print (separatore); if (ritornoACapo) System.out.println (centesimi); else System.out.print (centesimi); } 6.6 Binding dinamico class Accesso { private int oraInizio; private int oraFine; public void assegnaOraInizio (int ora) { oraInizio = ora; } public void assegnaOraFine (int ora) { oraFine = ora; } public boolean verificaOrario (Tempo t) { if (t.leggiOra() >= oraInizio && t.leggiOra() <= oraFine) return true; else { t.visualizza(true); return false; } } } 6.7 Operatori sulle istanze if (t instanceof Tempo2) ((Tempo2) t).leggiCentesimi(); 6.8 Costruttori e finalizzazione public Tempo (int ora, int minuto, int secondo) { assegnaTempo (ora, minuto, secondo); } mioAccesso.verificaOrario (new Tempo(oraCorrente, 0, 0)); class Tempo3 { private Tempo oreMinSec; int centesimi; void assegnaTempo (int ora, int minuto, int secondo, int cent) { oreMinSec.assegnaTempo (ora, minuto, secondo); centesimi = cent; } int leggiOra() { return oreMinSec.leggiOra(); } . . } class Tempo3 { private Tempo oreMinSec = new Tempo (); int centesimi; void assegnaTempo (int ora, int minuto, int secondo, int cent) { oreMinSec.assegnaTempo (ora, minuto, secondo); centesimi = cent; } int leggiOra() { return oreMinSec.leggiOra(); } . . } 6.9 super public void visualizza (boolean ritornoACapo) { super.visualizza (false); System.out.print (separatore); if (ritornoACapo) System.out.println (centesimi); else System.out.print (centesimi); } Tempo2 (int ora, int minuto, int secondo, int centesimo) { super (ora, minuto, secondo); this.centesimo = centesimo; } 6.10 Variabili e metodi di classe class ProvaTempo2 { static private Tempo tempoStatico = new Tempo(); public static void main (String argv[]) { System.out.println("Inizio"); Tempo mioTempo; mioTempo = new Tempo(); mioTempo.assegnaTempo(22,30,5); tempoStatico.assegnaTempo(1,2,3); mioTempo.visualizza(true); tempoStatico.visualizza(true); } static { Tempo.separatore = ':'; System.out.println("Static"); } } 6.12 Un esempio riepilogativo abstract class VettoreOrdinato { private Object vettore[]; private int maxElementi; private int curElementi; public VettoreOrdinato (int maxElementi) { this.maxElementi = maxElementi; vettore = new Object[maxElementi]; curElementi = 0; } protected boolean aggiungi (Object elemento) { if (elemento != null && curElementi < maxElementi) { vettore[curElementi++] = elemento; return true; } else return false; } public Object leggi (int indice) { if (indice >= 0 && indice < curElementi) return (vettore[indice]); else return null; } public int maxElementi () { return maxElementi; } public int elementi () { return curElementi; } public void ordina () { int s, i, j, num; Object temp; num = curElementi; for (s = num / 2; s > 0; s /= 2) for (i = s; i < num; i++) for (j = i - s; j >= 0; j -= s) if (confronta (vettore[j], vettore[j + s])) { temp = vettore[j]; vettore[j] = vettore[j + s]; vettore[j + s] = temp; } } abstract protected boolean confronta (Object elemento1, Object elemento2); } class Tempo { protected int ore; protected int minuti; protected int secondi; static public char separatore; public Tempo () { ore = minuti = secondi = 0; } public Tempo (int ora, int minuto, int secondo) { this(); assegnaTempo (ora, minuto, secondo); } public int assegnaTempo (int ora, int minuto, int secondo) { if (ora >= 0 && ora < 24 && minuto >= 0 && minuto < 60 && secondo >= 0 && secondo < 60) { ore = ora; minuti = minuto; secondi = secondo; return 0; } else return -1; } public int leggiOra () { return ore; } public int leggiMinuti () { return minuti; } public int leggiSecondi () { return secondi; } public void aggiungiOre (int numOre) { ore = ore + numOre; while (ore > 23) ore = ore - 24; } public void visualizza (boolean ritornoACapo) { System.out.print (ore); System.out.print (separatore); System.out.print (minuti); System.out.print (separatore); if (ritornoACapo) System.out.println (secondi); else System.out.print (secondi); } public boolean maggioreDi (Tempo t) { if (ore > t.ore || ore == t.ore && minuti > t.minuti || ore == t.ore && minuti == t.minuti && secondi > t.secondi) return true; else return false; } } class VettoreTempo extends VettoreOrdinato { VettoreTempo () { super (10); } VettoreTempo (int elementi) { super (elementi); } protected boolean aggiungi (Object elemento) { return false; } protected boolean aggiungi (Tempo elemento) { return super.aggiungi(elemento); } protected boolean confronta (Object elemento1, Object elemento2) { return ((Tempo) elemento1).maggioreDi((Tempo) elemento2); } } class ProvaVettore { public static void main (String argv[]) { VettoreTempo vt = new VettoreTempo (12); int ore, minuti, secondi; Tempo.separatore = ':'; for (int i = 0; i < 12; i++) { ore = (int) (Math.random () * 24); minuti = (int) (Math.random () * 60); secondi = (int) (Math.random () * 60); vt.aggiungi (new Tempo (ore, minuti, secondi)); } vt.ordina(); for (int i = 0; i < vt.elementi(); i++) ((Tempo)vt.leggi (i)).visualizza(true); } } Capitolo 7 - Interfacce e package class Punto { int x; int y; public Punto (int x, int y) { this.x = x; this.y = y; } int leggiX() { return x; } int leggiY() { return y; } int distanza() { return (int) Math.sqrt(x * x + y * y); } } interface nome-interfaccia [extends interfaccia-genitrice] { [tipo1 nome-variabile1 = valore1; ... tipoN nome-variabileN = valoreN;] tipo-restituito1 metodo1(arg1); ... tipo-restituitoN metodoN(argN); } interface Ordinabile { public boolean maggioreDi (Ordinabile o); } class Punto implements Ordinabile { int x; int y; public Punto (int x, int y) { this.x = x; this.y = y; } int leggiX() { return x; } int leggiY() { return y; } int distanza() { return (int) Math.sqrt(x * x + y * y); } public boolean maggioreDi (Ordinabile o) { if (o instanceof Punto) return distanza() > ((Punto) o).distanza(); else return false; } } class VettoreOrdinato { private Ordinabile vettore[]; private int maxElementi; private int curElementi; public VettoreOrdinato (int maxElementi) { this.maxElementi = maxElementi; vettore = new Ordinabile[maxElementi]; curElementi = 0; } public boolean aggiungi (Ordinabile elemento) { if (elemento != null && curElementi < maxElementi) { vettore[curElementi++] = elemento; return true; } else return false; } public Ordinabile leggi (int indice) { if (indice >= 0 && indice < curElementi) return (vettore[indice]); else return null; } public int maxElementi () { return maxElementi; } public int elementi () { return curElementi; } public void ordina () { int s, i, j, num; Ordinabile temp; num = curElementi; for (s = num / 2; s > 0; s /= 2) for (i = s; i < num; i++) for (j = i - s; j >= 0; j -= s) if (vettore[j].maggioreDi (vettore[j + s])) { temp = vettore[j]; vettore[j] = vettore[j + s]; vettore[j + s] = temp; } } } class TestOrdinamento2 { public static void main (String argv[]) { VettoreOrdinato vo = new VettoreOrdinato(10); vo.aggiungi (new Punto(30,40)); vo.aggiungi (new Punto(300,400)); vo.aggiungi (new Punto(3,4)); vo.ordina(); for (int i = 0; i < vo.elementi(); i++) System.out.println(((Punto)(vo.leggi (i))).distanza()); } } 7.2 I package package nome-pkg1[.nome-pkg2[... .nome-pkgN]]; public class Punto implements ordinamento.Ordinabile { ... public boolean maggioreDi (ordinamento.Ordinabile o) { if (o instanceof Punto) return distanza() > ((Punto) o).distanza(); else return false; } } import nome-pkg1[.nome-pkg2[... .nome-pkgN]].nome-classe; import ordinamento.*; // oppure import ordinamento.VettoreOrdinato; class TestOrdinamento3 { public static void main (String argv[]) { VettoreOrdinato vo = new VettoreOrdinato(10); vo.aggiungi (new Punto(30,40)); vo.aggiungi (new Punto(300,400)); vo.aggiungi (new Punto(3,4)); vo.ordina(); for (int i = 0; i < vo.elementi(); i++) System.out.println(((Punto)(vo.leggi (i))).distanza()); } } import java.lang.*; Capitolo 8 - Classi standard package java.applet package java.awt package java.awt.datatransfer package java.awt.event package java.awt.image package java.awt.peer package java.io package java.lang package java.lang.reflect package java.net package java.rmi package java.rmi.dgc package java.rmi.registry package java.rmi.server package java.security package java.security.acl package java.security.interfaces package java.sql package java.text package java.util package java.util.zip 8.2 La classe Object Tempo t1 = new Tempo; try { Tempo t2 = (Tempo)t1.clone(); } catch (Exception e) { System.out.println ("Classe non clonabile"); } 8.3 La gestione delle stringhe System.out.println ("Essere o non essere"); System.out.println ("Essere o non essere".length()); char c[] = { 'a', 'b', 'c' }; StringBuffer sb = new StringBuffer (new String (c)); String str1 = "Marco"; String str2 = new String(str1); System.out.println (str1 == str2); System.out.println (str1.equals(str2)); System.out.println (str1.equals("marco")); System.out.println (str1.equalsIgnoreCase("marco")); System.out.println (str1.compareTo("Andrea")); System.out.println (str1.compareTo("Marco")); System.out.println (str1.compareTo("Ugo")); 8.3.2 Estrazione di caratteri String str = "dsXdsk•Xk•X•ldkxX"; int conto = 0; for (int i = 0; i < str.length(); i++) if (str.charAt(i) == 'X') conto++; System.out.println (conto); String str = "foresta"; System.out.println (str.substring(2)); System.out.println (str.substring(3, 6)); 8.3.5 Altri metodi 8.3.6 La classe StringBuffer public StringBuffer append(boolean b); public StringBuffer append(char c); public StringBuffer append(int i); public StringBuffer append(long l); public StringBuffer append(float f); public StringBuffer append(double d); public StringBuffer append(Object obj); public StringBuffer append(char[] str); public StringBuffer append(char[] str, int offset, int len); public StringBuffer append(String str); String dataOggi = new StringBuffer() .append("Oggi Š il ") .append(giorno) .append(" di ") .append(mese) .toString(); String dataOggi = "Oggi Š il " + giorno + " di " + mese; Double d = 1.23; String dStringa = "" + d; import java.util.Vector; class SuiVettori { String p1, p2; public static void main (String argv[]) { Vector v = new Vector(3); System.out.println("capacit… >" + v.capacity()); System.out.println("n.elementi >" + v.size()); v.addElement ("a"); v.addElement ("b"); v.addElement ("d"); v.addElement ("e"); v.insertElementAt ("c", 2); System.out.println("capacit… >" + v.capacity()); System.out.println("n.elementi >" + v.size()); System.out.println("primo elemento >" + v.firstElement()); System.out.println("ultimo elemento >" + v.lastElement()); for (int i = 0; i < v.size(); i++) System.out.println("elemento a " + i + " >" + v.elementAt(i)); } } 8.5 Classi involucro ? Bignum ? Boolean ? Byte ? Character ? Double ? Float ? Integer ? Long ? Number ? Short 8.5.3 Classi involucro per numeri a virgola mobile if (d == Double.NEGATIVE_INFINITY) System.out.println ("negativo diviso per 0"); else if (d == Double.POSITIVE_INFINITY) System.out.println ("positivo diviso per 0"); 8.5.4 Classe Bignum 8.6 Funzioni matematiche public final class Math { public static final double E = 2.7182818284590452354; public static final double PI = 3.14159265358979323846; public static double sin(double a); public static double cos(double a); public static double tan(double a); public static double asin(double a); public static double acos(double a); public static double atan(double a); public static double atan2(double a, double b); public static double exp(double a); public static double log(double a); public static double sqrt(double a); public static double pow(double a, double b); public static double IEEEremainder(double f1, double f2); public static double ceil(double a); public static double floor(double a); public static double rint(double a); public static int round(float a); public static long round(double a); public static double random(); public static int abs(int a); public static long abs(long a); public static float abs(float a); public static double abs(double a); public static int min(int a, int b); public static long min(long a, long b); public static float min(float a, float b); public static double min(double a, double b); public static int max(int a, int b); public static long max(long a, long b); public static float max(float a, float b); public static double max(double a, double b); } Capitolo 9 - La gestione delle eccezioni 9.1 Istruzioni try e catch try { try-istruzione-1; [try-istruzione-2; ] ... [try-istruzione-N; ] } catch (Classe-eccezione1 e1) { [catch1-istruzione-1; ] ... [catch1-istruzione-N; ] } [catch (Classe-eccezione2 e2) { [catch2-istruzione-1; ] ... [catch2-istruzione-N; ] } ... catch (Classe-eccezioneN eN) { [catchN-istruzione-1; ] ... [catchN-istruzione-N; ] } ] [finally { [finally-istruzione-1; ] ... [finally-istruzione-N; ] }] class Eccezioni { int array1[] = { 100, 200 }; int array2[]; int metodo1 (int arr[], int ind, int div) { int Return = 0; try { Return = arr[ind] / div; } catch (ArithmeticException e) { System.out.println ("metodo1: Eccezione aritmetica:" + e); } System.out.println ("Fine metodo1"); return Return; } public static void main (String argv[]) { Eccezioni ecc = new Eccezioni(); try { ecc.metodo1(ecc.array1, 0, 0); } catch (ArrayIndexOutOfBoundsException e) { System.out.println ("Eccezione indice array:" + e); } catch (ArithmeticException e) { System.out.println ("main: Eccezione aritmetica:" + e); } try { ecc.metodo1(ecc.array1, -1, 1); } catch (ArrayIndexOutOfBoundsException e) { System.out.println ("main: Eccezione indice array:" + e); } catch (ArithmeticException e) { System.out.println ("main: Eccezione aritmetica:" + e); } try { ecc.metodo1(ecc.array2, 1, 1); } catch (ArrayIndexOutOfBoundsException e) { System.out.println ("main: Eccezione indice array:" + e); } catch (ArithmeticException e) { System.out.println ("main: Eccezione aritmetica:" + e); } System.out.println ("Fine main"); } } } catch (ArithmeticException e) { System.out.println ("metodo1: Eccezione aritmetica:" + e System.out.println ("Premi return per continuare"); try { System.in.read(); } catch (Exception e2) { } } 9.2 finally int metodo1 (int arr[], int ind, int div) { int Return = 0; try { Return = arr[ind] / div; } catch (ArithmeticException e) { System.out.println ("metodo1: Eccezione aritmetica:" + e); } finally { System.out.println ("metodo1:finally 1"); } try { return Return; } finally { System.out.println ("Fine metodo1"); } } 9.4 throws static int leggi(boolean numero) { byte b[] = new byte[9]; int Return = 0; try { System.in.read(b); } catch (Exception e) { } if (intero) for (int i = 0; i < b.length; i++) if (b[i] >= '0' && b[i] <= '9') Return = Return * 10 + b[i] - '0'; else break; else if (b[0] >= ' ') Return = b[0]; return Return; } dichiarazione-metodo (lista-argomenti) throws Classe-eccezione1 [,Classe-eccezione2 ... [,Classe-eccezioneN]] import java.io.*; class Input { public static void main (String argv[]) { int inp = 0; do { try { inp = leggi(true); } catch (Exception e) { } System.out.print ("hai inserito "); System.out.println (inp); } while (inp != 0); do { try { inp = leggi(false); } catch (Exception e) { } System.out.print ("hai inserito "); System.out.println ((char)inp); } while (inp != 0); } static int leggi(boolean num) throws IOException { byte b[] = new byte[9]; int Return = 0; System.in.read(b); if (num) for (int i = 0; i < b.length; i++) if (b[i] >= '0' && b[i] <= '9') Return = Return * 10 + b[i] - '0'; else break; else if (b[0] >= ' ') Return = b[0]; return Return; } } public static void main (String argv[]) throws Exception { int inp = 0; do { inp = leggi(true); System.out.print ("hai inserito "); System.out.println (inp); } while (inp != 0); do { inp = leggi(false); System.out.print ("hai inserito "); System.out.println ((char)inp); } while (inp != 0); } 9.6 Un esempio riepilogativo public class TempoException extends Exception { } A questo punto possiamo modificare la classe Tempo. public class Tempo { protected int ore; protected int minuti; protected int secondi; static public char separatore; public Tempo () { ore = minuti = secondi = 0; } public Tempo (int ora, int minuto, int secondo) throws TempoException { this(); assegnaTempo (ora, minuto, secondo); } public void assegnaTempo (int ora, int minuto, int secondo) throws TempoException { if (ora >= 0 && ora < 24 && minuto >= 0 && minuto < 60 && secondo >= 0 && secondo < 60) { ore = ora; minuti = minuto; secondi = secondo; } else throw new TempoException(); } /* ... */ /* Altri metodi della classe Tempo */ /* ... */ } public class EccTempo { public static void main (String argv[]) { try { Tempo t = new Tempo (99,99,99); } catch (TempoException e) { System.out.println ("Errore: " + e); } } } public class TempoException extends Exception { String msg; TempoException () { msg = ""; } TempoException (String msg) { this.msg = msg; } public String toString () { return "Errore nella classe Tempo: " + msg; } } throw new TempoException("argomenti incongruenti " + ora + "," + minuto + "," + secondo); Capitolo 10 - I thread public class ProvaThread implements Runnable { public static void main (String argv[]) { System.out.println ("Thread corrente: " + Thread.currentThread()); ProvaThread pt = new ProvaThread(); Thread t = new Thread(pt); t.start (); try { Thread.sleep (2000); } catch (InterruptedException e) { } System.out.println ("Fine main"); } public void run () { System.out.println ("Thread run: " + Thread.currentThread()); for (int i = 0; i < 5; i++) { System.out.println (i); try { Thread.currentThread().sleep (1000); } catch (InterruptedException e) { } } System.out.println ("Fine run"); } } Thread corrente: Thread[main,5,system] Thread run: Thread[Thread-0,5,system] 0 1 Fine main 2 3 4 Fine run class MioThread extends Thread { public void run () { System.out.println ("Thread run: " + Thread.currentThread()); for (int i = 0; i < 5; i++) { System.out.println (i); try { Thread.currentThread().sleep (1000); } catch (InterruptedException e) { } } System.out.println ("Fine run"); } } public class ProvaThread { public static void main (String argv[]) { System.out.println ("Thread corrente: " + Thread.currentThread()); MioThread t = new MioThread(); t.start (); try { Thread.sleep (2000); } catch (InterruptedException e) { } System.out.println ("Fine main"); } } 10.2 La sincronizzazione public class ProvaThread2 implements Runnable { public static void main (String argv[]) { ProvaThread2 pt = new ProvaThread2(); Thread t = new Thread (pt); t.start (); pt.m2(); } public void run() { m1(); } synchronized void m1 () { for (char c = 'A'; c < 'F'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } void m2 () { for (char c = '1'; c < '6'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } } public class ProvaThread3 implements Runnable { public static void main (String argv[]) { ProvaThread3 pt = new ProvaThread3(); ProvaThread3 pt2 = new ProvaThread3(); Thread t = new Thread (pt); t.start (); pt2.m1(); } public void run() { m1(); } synchronized void m1 () { for (char c = 'A'; c < 'F'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } } public class ProvaThread4 implements Runnable { public static void main (String argv[]) { ProvaThread4 pt = new ProvaThread4(); Thread t = new Thread (pt); t.start (); m2(); } public void run() { m1(); } synchronized void m1 () { for (char c = 'A'; c < 'F'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } static synchronized void m2 () { for (char c = '1'; c < '6'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } } synchronized (istanza) { istruzione1; ... istruzioneN; } public class ProvaThread5 implements Runnable { public static void main (String argv[]) { ProvaThread5 pt = new ProvaThread5(); Thread t = new Thread (pt); t.start (); synchronized (pt) { pt.m2(); } } public void run() { m1(); } synchronized void m1 () { for (char c = 'A'; c < 'F'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } void m2 () { for (char c = '1'; c < '6'; c++) { System.out.println (c); try { Thread.sleep (1000); } catch (InterruptedException e) { } } } } class ProvaThread6 { public static void main(String[] args) { ProvaThread6 pt = new ProvaThread6(); synchronized(pt) { synchronized(pt) { System.out.println("fatto!"); } } } } 10.4 Comunicazione fra thread class Visualizza implements Runnable { Monitor monitor; Visualizza (Monitor m) { monitor = m; Thread t = new Thread (this); t.setDaemon(true); t.start (); } public void run () { for ( ; ; ) System.out.println (monitor.ricevi()); } } class Monitor { private boolean pieno = false; private String buffer; synchronized void spedisci (String msg) { if (pieno) try { wait(); } catch (InterruptedException e) { } pieno = true; notify (); buffer = msg; } synchronized String ricevi () { if (!pieno) try { wait(); } catch (InterruptedException e) { } pieno = false; notify (); return buffer; } } public class ProvaThread7 { public static void main (String argv[]) { Monitor monitor = new Monitor(); String messaggi[] = { "Esempio", "di", "comunicazione", "fra", "thead" }; Visualizza v = new Visualizza (monitor); for (int i = 0; i < messaggi.length; i++) monitor.spedisci(messaggi[i]); } } Capitolo 11 - Ambiente di esecuzione 11.1 Classe Dictionary e sottoclassi import java.util.Enumeration; import java.util.Hashtable; public class Eta { public static void main (String argv[]) { Hashtable ht = new Hashtable(); ht.put ("Marco", new Integer (39)); ht.put ("Luigi", new Integer (33)); ht.put ("Claudio", new Integer (37)); System.out.println("Et… di Luigi=" + (Integer) ht.get("Luigi")); Enumeration enum = ht.keys(); while (enum.hasMoreElements()) System.out.println((String) enum.nextElement()); enum = ht.elements(); while (enum.hasMoreElements()) System.out.println((Integer) enum.nextElement()); } } import java.util.Enumeration; import java.util.Properties; class Persona { static private Properties datiDefault = new Properties(); public Properties dati = new Properties(datiDefault); public Persona (String nome) { dati.put ("Nome", nome); } static public Enumeration tipiDati() { return datiDefault.keys(); } static { datiDefault.put ("Nome", "sconosciuto"); datiDefault.put ("Nazionalit…", "sconosciuta"); datiDefault.put ("Et…", "sconosciuta"); } } public class Gente { public static void main (String argv[]) { Persona gente[] = new Persona[3]; gente[0] = new Persona("Marco"); gente[0].dati.put ("Nazionalit…", "Italiana"); gente[1] = new Persona("Claudio"); gente[1].dati.put ("Et…", "37"); gente[2] = new Persona("Luigi"); gente[2].dati.put ("Et…", "33"); gente[2].dati.put ("Nazionalit…", "Italiana"); for (int i = 0; i < gente.length; i++) mostra (gente[i]); try { System.in.read(); } catch (Exception e) {} } static public void mostraPersona (Persona p) { String chiave; Enumeration enum = Persona.tipiDati(); while (enum.hasMoreElements()) System.out.println ( (chiave = (String) enum.nextElement()) + " = " + p.dati.getProperty (chiave)); System.out.println ("-------"); } } 11.3 Il metodo main file Main1.java: public class Main1 { public static void main (String argv[]) { System.out.println("Main1"); Main2 m2 = new Main2(); } static { System.out.println("Main1 static"); } } file Main2.java: public class Main2 { public static void main (String argv[]) { System.out.println("Main2"); } static { System.out.println("Main2 static"); } } public class Main3 { public static void main (String argv[]) { for (int i = 0; i < argv.length; i++) System.out.println("N." + i +"["+ argv[i] + "]"); try { System.in.read(); } catch (Exception e) {} } } 11.5 Classi Runtime e Process try { Runtime.getRuntime().exec("notepad"); } catch (Exception e) { System.out.println ("Errore exec:" + e); } try { Runtime.getRuntime().exec("notepad Main3.java"); } catch (Exception e) { System.out.println ("Errore exec:" + e); } try { Runtime.getRuntime().exec("java Main3 \"Š una frase\" Š una frase"); } catch (Exception e) { System.out.println ("Errore exec:" + e); } import java.io.*; class OutFiglio implements Runnable { InputStream in; OutFiglio (InputStream in) { this.in = in; Thread t = new Thread(this); t.setDaemon(true); t.start(); } public void run() { String s; byte b[] = new byte[1024]; int len; try { while ((len = in.read(b)) >= 0) { s = new String(b, 0, len); System.out.print (s); } } catch (Exception e) { return; } } } public class Exec1 { public static void main (String argv[]) { try { Process p = Runtime.getRuntime().exec("java Main3 \"Š una frase\" Š una frase"); new OutFiglio (p.getInputStream()); int exitCode = p.waitFor(); System.out.println ("Codice = " + exitCode); } catch (Exception e) { System.out.println ("Errore exec:" + e); } } } class Main3 { public static void main (String argv[]) { for (int i = 0; i < argv.length; i++) System.out.println("N." + i +"["+ argv[i] + "]"); Runtime.getRuntime().exit (99); } } Capitolo 12 - La gestione dell'I/O 12.1 Classe File import java.io.*; public class UsoDelDisco { static public void main (String argv[]) { UsoDelDisco ist = new UsoDelDisco(argv); } UsoDelDisco (String argv[]) { if (argv.length != 1) { System.err.println ("Uso: java " + this.getClass().getName() + " "); return; } leggiDir (argv[0]); } private int leggiDir (String file) { int Return = 0; File f = new File(file); if (f.exists()) { Return += f.length(); if (f.isDirectory()) { String list[] = f.list(); for (int i = 0; i < list.length; i++) Return += leggiDir (file + '/' + list[i]); } System.out.println (file + '=' + Return); } return Return; } } 12.2 Flussi di input import java.io.*; public class VediFile { static public void main (String argv[]) { VediFile ist = new VediFile(argv); } VediFile (String argv[]) { if (argv.length != 1) { System.err.println ("Uso: java " + this.getClass().getName() + " "); return; } FileInputStream in; try { in = new FileInputStream(argv[0]); } catch (Exception e) { System.err.println ("Errore apertura file :" + e); return; } int c; try { while ((c = in.read()) > 0) System.out.print ((char) c); in.close(); } catch (Exception e) { System.err.println ("Errore lettura file :" + e); } } } 12.3 Flussi di output import java.io.*; public class CopiaFile { static public void main (String argv[]) { CopiaFile ist = new CopiaFile(argv); } CopiaFile (String argv[]) { if (argv.length != 2) { System.err.println ("Uso: java " + this.getClass().getName() + " "); return; } FileInputStream in; FileOutputStream out; try { in = new FileInputStream(argv[0]); out = new FileOutputStream(argv[1]); } catch (Exception e) { System.err.println ("Errore apertura file :" + e); return; } int c; try { while ((c = in.read()) > 0) out.write (c); in.close(); out.close(); } catch (Exception e) { System.err.println ("Errore copia file :" + e); return; } } } 12.4 Accesso casuale import java.io.*; public class CambiaByte { static public void main (String argv[]) { CambiaByte ist = new CambiaByte(argv); } CambiaByte (String argv[]) { if (argv.length != 3 || argv[1].length() != 1 || argv[2].length() != 1) { System.err.println ("Uso: java " + this.getClass().getName() + " "); return; } RandomAccessFile inOut; try { inOut = new RandomAccessFile(argv[0], "rw"); } catch (Exception e) { System.err.println ("Errore apertura file :" + e); return; } byte vecchio = (byte)argv[1].charAt(0); byte nuovo = (byte)argv[2].charAt(0); byte c; try { for ( ; ; ) { c = inOut.readByte(); if (c == vecchio) { inOut.seek (inOut.getFilePointer() - 1); inOut.writeByte (nuovo); } } } catch (EOFException e) { } catch (Exception e) { System.err.println ("Errore sostituzione in file :" + e); } try { inOut.close(); } catch (Exception e) { System.err.println ("Errore chiusura file :" + e); } } } 12.5 Gli oggetti persistenti import java.io.*; import java.util.Date; class Base implements Serializable { char chr[]; int num = 10; public Base (char [] chr, int num) { this.chr = chr; this.num = num; } } public class ScriviOggetto extends Base { String nome; ScriviOggetto (String nome, char chr[], int num) { super (chr, num); this.nome = nome; } public String toString () { return nome + "," + chr + "," + num; } public static void main (String argv[]) { char chr[]= { 'A','r','r','a','y' }; ScriviOggetto so = new ScriviOggetto ("Stringa", chr, 123456789); Date d = new Date(); System.out.println (so + " " + d); try { FileOutputStream f = new FileOutputStream("prova"); ObjectOutput s = new ObjectOutputStream(f); s.writeObject(so); s.writeObject(d); s.close(); } catch (Exception e) { System.out.println ("Errore in scrittura:" + e); } leggi(); } public static void leggi () { try { FileInputStream in = new FileInputStream("prova"); ObjectInputStream s = new ObjectInputStream(in); Object o = s.readObject(); Object d = s.readObject(); System.out.println (o + " " + d); } catch (Exception e) { System.out.println ("Errore in lettura:" + e); } } } public Base () { this.chr = new char[0]; } import java.io.*; import java.util.Date; public class LeggiOggetto { public static void main (String argv[]) { try { FileInputStream in = new FileInputStream("prova"); ObjectInputStream s = new ObjectInputStream(in); Object o = s.readObject(); Object d = s.readObject(); System.out.println (o + " " + d); } catch (Exception e) { System.out.println ("Errore in lettura:" + e); } } } Capitolo 13 - L'interfaccia grafica 13.1 L'AWT import java.awt.*; public class FinestraVuota extends Frame { public static void main (String argv[]) { FinestraVuota ist = new FinestraVuota(); System.out.println ("Esco da main"); } FinestraVuota () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); } } 13.2 Eventi ? ActionListener ? AdjustmentListener ? ComponentListener ? FocusListener ? ItemListener ? KeyListener ? MouseListener ? MouseMotionListener ? WindowListener import java.awt.*; import java.awt.event.*; public class Eventi extends Frame { Ascoltatore asc = new Ascoltatore(); public static void main (String argv[]) { Eventi ist = new Eventi(); } Eventi () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); addWindowListener(asc); } } class Ascoltatore implements WindowListener { public void windowClosed (WindowEvent evt) { System.out.println (evt); System.exit(0); } public void windowClosing(WindowEvent evt) { evt.getWindow().dispose(); System.out.println (evt); } public void windowDeiconified(WindowEvent evt) { System.out.println (evt); } public void windowIconified(WindowEvent evt) { System.out.println (evt); } public void windowOpened(WindowEvent evt) { System.out.println (evt); } public void windowActivated(WindowEvent evt) { System.out.println (evt); } public void windowDeactivated(WindowEvent evt) { System.out.println (evt); } } java.awt.event.WindowEvent[WINDOW_CLOSING] on frame0 java.awt.event.WindowEvent[WINDOW_DEACTIVATED] on frame0 java.awt.event.WindowEvent[WINDOW_CLOSED] on frame0 import java.awt.*; import java.awt.event.*; public class Eventi extends Frame { Ascoltatore asc = new Ascoltatore(); public static void main (String argv[]) { Eventi ist = new Eventi(); } Eventi () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); addWindowListener(asc); } } class Ascoltatore extends WindowAdapter { public void windowClosed (WindowEvent evt) { System.out.println (evt); System.exit(0); } public void windowClosing(WindowEvent evt) { evt.getWindow().dispose(); System.out.println (evt); } } import java.awt.*; import java.awt.event.*; public class Eventi extends Frame { WindowAdapter asc; public static void main (String argv[]) { Eventi ist = new Eventi(); } Eventi () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); class Ascoltatore extends WindowAdapter { public void windowClosed (WindowEvent evt) { System.out.println (evt); System.exit(0); } public void windowClosing(WindowEvent evt) { Eventi.this.dispose(); System.out.println (evt); } } asc = new Ascoltatore(); addWindowListener(asc); } } import java.awt.*; import java.awt.event.*; public class Eventi extends Frame { WindowAdapter asc; public static void main (String argv[]) { Eventi ist = new Eventi(); } Eventi () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); asc = new WindowAdapter() { public void windowClosed (WindowEvent evt) { System.out.println (evt); System.exit(0); } public void windowClosing(WindowEvent evt) { Eventi.this.dispose(); System.out.println (evt); } }; addWindowListener(asc); } } 13.3 Il metodo paint public void paint (Graphics g) { g.drawString ("Il primo programma grafico", 5, 40); } import java.awt.*; import java.awt.event.*; public class Tastiera extends Frame implements KeyListener { String testo = ""; public static void main (String argv[]) { Tastiera ist = new Tastiera(); } Tastiera () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); addKeyListener (this); setVisible(true); } public void paint(Graphics g) { g.drawString (testo, 5, 40); } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { testo += e.getKeyChar(); repaint(); } } 13.5 Il mouse import java.awt.*; import java.awt.event.*; public class Mouse extends Frame implements MouseMotionListener, MouseListener { int x1 = -1, x2, y1, y2; public static void main (String argv[]) { Mouse ist = new Mouse(); } Mouse () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); addMouseListener (this); addMouseMotionListener (this); setVisible(true); } public void paint(Graphics g) { if (x1 > 0) { int x0, y0, larghezza, altezza; if (x1 < x2) { x0 = x1; larghezza = x2 - x1; } else { x0 = x2; larghezza = x1 - x2; } if (y1 < y2) { y0 = y1; altezza = y2 - y1; } else { y0 = y2; altezza = y1 - y2; } g.drawRect (x0, y0, larghezza, altezza); } } public void mouseDragged(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); repaint(); } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x1 = -1; } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } public void update(Graphics g) { paint (g); } 13.6 I colori public final static Color white = new Color(255, 255, 255); public final static Color lightGray = new Color(192, 192, 192); public final static Color gray = new Color(128, 128, 128); public final static Color darkGray = new Color(64, 64, 64); public final static Color black = new Color(0, 0, 0); public final static Color red = new Color(255, 0, 0); public final static Color pink = new Color(255, 175, 175); public final static Color orange = new Color(255, 200, 0); public final static Color yellow = new Color(255, 255, 0); public final static Color green = new Color(0, 255, 0); public final static Color magenta = new Color(255, 0, 255); public final static Color cyan = new Color(0, 255, 255); public final static Color blue = new Color(0, 0, 255); import java.awt.*; public class Colori extends Frame { public static void main (String argv[]) { Colori ist = new Colori(); } Colori () { setBackground (Color.lightGray); setForeground (Color.red); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); } public void paint (Graphics g) { g.drawString ("Stringa rossa", 5, 40); g.setColor (Color.green); g.drawString ("Stringa verde", 5, 80); } } 13.7 I font public Font(String nome, int stile, int dim) import java.awt.*; public class ListaFont extends Frame { public static void main (String argv[]) { ListaFont ist = new ListaFont(); } ListaFont () { String listaFont[] = getToolkit().getFontList(); for (int i = 0; i < listaFont.length; i++) System.out.println (listaFont[i]); System.exit(0); } } import java.awt.*; public class FontTipografici extends Frame { public static void main (String argv[]) { FontTipografici ist = new FontTipografici(); } FontTipografici () { setFont (new Font ("Courier", Font.PLAIN, 12)); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); } public void paint (Graphics g) { g.drawString ("Stringa Courier", 5, 40); g.setFont (new Font ("Dialog", Font.PLAIN, 12)); g.drawString ("Stringa Dialog", 5, 80); } } import java.awt.*; public class TestoCentrato extends Frame { String testo[] = { "Questo", "testo", "Š", "centrato" }; public static void main (String argv[]) { TestoCentrato ist = new TestoCentrato(); } TestoCentrato () { setBounds (30, 10, 300, 200); setTitle (getClass().getName()); setVisible(true); } public void paint (Graphics g) { FontMetrics fm = g.getFontMetrics(); Dimension d = getSize(); Insets ins = getInsets(); int larghezza = d.width - ins.left - ins.right; int altezza = d.height - ins.top - ins.bottom; int altFont = fm.getHeight(); int totAlt = altFont * testo.length; int y0 = ins.top + altFont + (altezza - totAlt) / 2; for (int i = 0; i < testo.length; i++) { int x0 = ins.left + (larghezza - fm.stringWidth(testo[i])) / 2; g.drawString (testo[i], x0, y0 + i * altFont); } } } Capitolo 14 - I controlli grafici 14.1 Bottoni import java.util.Date; import java.awt.*; import java.awt.event.*; public class Bottoni extends Frame implements ActionListener { Date data = new Date(); public static void main (String argv[]) { Bottoni ist = new Bottoni(); } Bottoni () { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); Button bData = new Button("Data"); bData.setBounds (50, 150, 50, 30); bData.addActionListener (this); Button bEsci = new Button("Esci"); bEsci.setBounds (200, 150, 50, 30); bEsci.addActionListener (this); add (bData); add (bEsci); setVisible(true); } public void paint (Graphics g) { g.drawString (data.toString(), 5, 40); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Esci")) System.exit(0); if (e.getActionCommand().equals("Data")) { data = new Date(); repaint(); } } } 14.2 Input di testi import java.awt.*; import java.awt.event.*; public class LineaDiTesto extends Frame implements ActionListener { TextField t1; TextField t2; public static void main (String argv[]) { LineaDiTesto ist = new LineaDiTesto(); } LineaDiTesto () { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); Button bData = new Button("Scambia"); bData.setBounds (50, 150, 50, 30); bData.addActionListener (this); Button bEsci = new Button("Esci"); bEsci.setBounds (200, 150, 50, 30); bEsci.addActionListener (this); t1 = new TextField(); t1.setBounds (50, 50, 50, 20); t2 = new TextField(); t2.setBounds (200, 50, 50, 20); add (t1); add (t2); add (bData); add (bEsci); setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Esci")) System.exit(0); if (e.getActionCommand().equals("Scambia")) { String scambio = t1.getText(); t1.setText(t2.getText()); t2.setText(scambio); } } } 14.3 Etichette import java.awt.*; public class Etichette extends Frame { public static void main (String argv[]) { Etichette ist = new Etichette(); } Etichette () { setLayout (null); setBackground (Color.lightGray); setForeground (Color.red); setFont (new Font("Courier", Font.PLAIN, 12)); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); Label lRC = new Label ("Stringa rossa Courier"); lRC.setBounds (5, 40, 200, 30); Label lVD = new Label ("Stringa verde Dialog"); lVD.setBounds (5, 80, 200, 30); lVD.setFont (new Font("Dialog", Font.PLAIN, 12)); lVD.setForeground (Color.green); add(lRC); add(lVD); setVisible(true); } } 14.4 La classe Checkbox import java.awt.*; import java.awt.event.*; public class CasellaControllo extends Frame implements ItemListener { Checkbox cTest1; Checkbox cTest2; Label lT1; Label lT2; public static void main (String argv[]) { CasellaControllo ist = new CasellaControllo(); } CasellaControllo() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); cTest1 = new Checkbox("Test1"); cTest1.setBounds (50, 50, 50, 20); cTest1.addItemListener (this); cTest2 = new Checkbox("Test2"); cTest2.setBounds (200, 50, 50, 20); cTest2.addItemListener (this); lT1 = new Label (); lT1.setBounds (50, 100, 250, 20); lT2 = new Label (); lT2.setBounds (50, 120, 250, 20); vediStato (cTest1, lT1); vediStato (cTest2, lT2); add(cTest1); add(cTest2); add(lT1); add(lT2); setVisible(true); } void vediStato (Checkbox c, Label l) { l.setText("nome:" + c.getLabel() + ", stato:" + (c.getState() ? "" : "NON ") + "SELEZIONATO"); } public void itemStateChanged(ItemEvent e) { if (e.getItem().equals ("Test1")) vediStato (cTest1, lT1); else if (e.getItem().equals ("Test2")) vediStato (cTest2, lT2); } } public class GruppoCaselle extends Frame implements ItemListener { CheckboxGroup gTest; Checkbox cTest1; Checkbox cTest2; Label lT; public static void main (String argv[]) { GruppoCaselle ist = new GruppoCaselle(); } GruppoCaselle() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); gTest = new CheckboxGroup (); cTest1 = new Checkbox("Test1", false, gTest); cTest1.setBounds (50, 50, 50, 20); cTest1.addItemListener (this); cTest2 = new Checkbox("Test2", false, gTest); cTest2.setBounds (200, 50, 50, 20); cTest2.addItemListener (this); lT = new Label (); lT.setBounds (50, 100, 250, 20); vediStato (gTest.getSelectedCheckbox()); add(cTest1); add(cTest2); add(lT); setVisible(true); } void vediStato (Checkbox c) { if (c == null) lT.setText("Nessuna Selezione"); else lT.setText("Selezione=" + c.getLabel()); } public void itemStateChanged(ItemEvent e) { vediStato (gTest.getSelectedCheckbox()); } } 14.6 La classe Choice import java.awt.*; import java.awt.event.*; public class Scelte extends Frame implements ItemListener { Choice chTest; Label lT; public static void main (String argv[]) { Scelte ist = new Scelte(); } Scelte() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); chTest = new Choice (); chTest.add ("Test1"); chTest.add ("Test2"); chTest.setBounds (50, 50, 100, 20); chTest.addItemListener (this); lT = new Label (); lT.setBounds (50, 100, 250, 20); vediStato (); add(chTest); add(lT); setVisible(true); } void vediStato () { lT.setText("Selezione=" + chTest.getSelectedItem()); } public void itemStateChanged(ItemEvent e) { vediStato (); } } 14.7 Liste import java.awt.*; import java.awt.event.*; public class Liste extends Frame implements ItemListener, ActionListener { List lTest; Label lT1; Label lT2; public static void main (String argv[]) { Liste ist = new Liste(); } Liste() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); lTest = new List (0, true); lTest.add ("Test zero"); lTest.add ("Test uno"); lTest.add ("Test due"); lTest.add ("Test tre"); lTest.add ("Test quattro"); lTest.add ("Test cinque"); lTest.setBounds (50, 50, 100, 80); lTest.addItemListener (this); lTest.addActionListener (this); lT1 = new Label (); lT1.setBounds (50, 160, 250, 20); lT2 = new Label (); lT2.setBounds (50, 180, 250, 20); vediStato (); add(lTest); add(lT1); add(lT2); setVisible(true); } void vediStato () { lT1.setText("Selezione=" + lTest.getSelectedItem()); String multi = "Multiple="; int indici[] = lTest.getSelectedIndexes(); for (int i = 0; i < indici.length; i++) multi += " " + indici[i]; lT2.setText(multi); } public void itemStateChanged(ItemEvent e) { vediStato (); } public void actionPerformed(ActionEvent e) { String elementi[] = lTest.getSelectedItems(); for (int i = 0; i < elementi.length; i++) System.out.println (elementi[i]); System.exit (0); } } 14.8 Barre di scorrimento import java.awt.*; import java.awt.event.*; public class BarraScorrimento extends Frame implements AdjustmentListener { Scrollbar sTest; Label lT; public static void main (String argv[]) { BarraScorrimento ist = new BarraScorrimento(); } BarraScorrimento() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); sTest = new Scrollbar (Scrollbar.HORIZONTAL, 400, 200, 0, 1000); sTest.setBlockIncrement (200); sTest.setBounds (50, 50, 150, 30); sTest.addAdjustmentListener (this); lT = new Label ("Valore=" + sTest.getValue()); lT.setBounds (50, 100, 250, 20); add(sTest); add(lT); setVisible(true); } public void adjustmentValueChanged(AdjustmentEvent e) { sTest.setValue(e.getValue()); lT.setText ("Valore=" + e.getValue()); } } 14.10 Menu import java.awt.*; import java.awt.event.*; public class MenuTest extends Frame implements ActionListener { Label lT; public static void main (String argv[]) { MenuTest ist = new MenuTest(); } MenuTest() { setLayout(null); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); MenuBar barraMenu = new MenuBar (); setMenuBar (barraMenu); Menu arch = new Menu("Archivio"); arch.add (new MenuItem("Nuovo")); arch.add (new MenuItem("Apri")); arch.add (new MenuItem("Aiuto")); arch.add (new MenuItem("Esci")); arch.addActionListener (this); barraMenu.add(arch); Menu sm = new Menu("Sotto menu"); sm.add (new MenuItem("Sotto menu 1")); sm.add (new MenuItem("Sotto menu 2")); sm.addActionListener (this); Menu modif = new Menu("Modifica"); modif.add (new MenuItem("Copia")); modif.add (new MenuItem("Incolla")); modif.add (new MenuItem("Cancella")); modif.addSeparator(); modif.add (sm); modif.addActionListener (this); barraMenu.add(modif); lT = new Label (); lT.setBounds (50, 150, 250, 20); add(lT); setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Esci")) System.exit(0); else lT.setText ("Menu:" + e.getActionCommand()); } } 14.11 Impaginazione automatica import java.awt.*; public class Bordo extends Frame { public static void main (String argv[]) { Bordo ist = new Bordo(); } Bordo () { setLayout (new BorderLayout()); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); add (new Button("Uno"), "North"); add (new Button("Due"), "East"); add (new Button("Tre"), "South"); add (new Button("Quattro"), "West"); add (new Button("Cinque"), "Center"); setVisible(true); } } import java.awt.*; public class Flusso extends Frame { public static void main (String argv[]) { Flusso ist = new Flusso(); } Flusso () { setLayout (new FlowLayout()); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); add (new Button("Uno")); add (new Button("Due")); add (new Button("Tre")); add (new Button("Quattro")); add (new Button("Cinque")); add (new Button("Sei")); add (new Button("Sette")); setVisible(true); } } import java.awt.*; public class Griglia extends Frame { public static void main (String argv[]) { Griglia ist = new Griglia(); } Griglia () { setLayout (new GridLayout(4,2)); setBounds (30, 10, 300, 200); setTitle (getClass().getName()); add (new Button("Uno")); add (new Button("Due")); add (new Button("Tre")); add (new Button("Quattro")); add (new Button("Cinque")); add (new Button("Sei")); add (new Button("Sette")); setVisible(true); } } Capitolo 15 - Internet e Java 15.3 Esecuzione di una applet [] [] ... [] import java.awt.*; import java.awt.event.*; import java.applet.*; public class Mouse extends Applet implements MouseMotionListener, MouseListener { int x1 = -1, x2, y1, y2; public Mouse () { addMouseListener (this); addMouseMotionListener (this); } public void paint(Graphics g) { if (x1 > 0) { int x0, y0, larghezza, altezza; if (x1 < x2) { x0 = x1; larghezza = x2 - x1; } else { x0 = x2; larghezza = x1 - x2; } if (y1 < y2) { y0 = y1; altezza = y2 - y1; } else { y0 = y2; altezza = y1 - y2; } g.drawRect (x0, y0, larghezza, altezza); } } public void mouseDragged(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); repaint(); } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { x1 = -1; } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } Mouse 15.4 Interazione tra browser e applet import java.applet.*; import java.awt.*; public class Contatore extends Applet implements Runnable { Thread thr; int cnt; public void init () { thr = new Thread(this); thr.start (); } public void run () { for ( ; ; ) { try { thr.sleep(1000); } catch (Exception e) { } cnt++; repaint(); } } public void start () { thr.resume(); } public void stop () { thr.suspend(); } public void paint (Graphics g) { g.drawString ("->" + cnt, 5, 40); } } 15.5 Immagini e suoni import java.applet.*; import java.awt.*; public class Immagine extends Applet { Image img; public void init () { img = getImage (getCodeBase(), "logo.jpg"); } public void paint (Graphics g) { g.drawImage (img, 0, 0, this); } } import java.applet.*; import java.awt.*; import java.awt.image.*; public class VideoAudio extends Applet { Image img; AudioClip auc; public void init () { img = getImage (getDocumentBase(), "logo.jpg"); auc = getAudioClip (getDocumentBase(), "spacemusic.au"); } public void start () { auc.loop(); } public void stop () { auc.stop(); } public void paint (Graphics g) { g.drawImage (img, 0, 0, this); } } Othello Appendice B - Othello come applet Il gioco dell'Othello, detto anche Reversi, consiste in una scacchiera di 64 caselle, 8 x 8, su cui all'inizio si trovano quattro pedine, due nere e due bianche, vedi figura B.1. Ognuno dei due avversari Š legato a un colore diverso e pu• mettere sulla scacchiera pedine del proprio colore. Una pedina pu• essere posta sulla scacchiera solo se racchiude una o pi— pedine del colore avversario fra se stessa e un'altra pedina del proprio colore. Tutte le pedine racchiuse in questo modo diventano del colore della pedina posta sulla scacchiera. Lo scopo del gioco Š di riempire la scacchiera con il maggior numero di pedine del proprio colore. Figura B.1 Posizioni di partenza del gioco Othello Viene qui presentato un'applet Java che permette di giocare a Othello contro il computer. In questa versione il computer gioca con le pedine nere mentre il giocatore ha le pedine bianche. Il giocatore pone le sue pedine effettuando un click con il mouse sulla casella prescelta. Alla prima mossa, il giocatore pu• passare il gioco al computer effettuando un click in una posizione non valida. La stessa cosa deve essere fatta nel caso in cui il giocatore non abbia mosse valide. Effettuando un click dopo la fine del gioco, si fa iniziare una nuova partita. Sono disponibili pi— livelli che possono essere impostati dal documento HTML per mezzo del parametro livello: il livello 1 Š per principianti e man mano che si sale di livello , aumenta la bravura del computer e i suoi tempi di elaborazione per generare una mossa. Il livello di default Š il 4. I sorgenti contengono in totale circa 500 linee di codice, esclusi i commenti, e le classi compilate occupano circa 10K, per cui possono essere eseguite da un browser Internet anche disponendo solo di una connessione via modem a bassa velocit…. Il codice Š stato scritto per essere pi— leggibile che efficiente, ma comunque, con le potenze elaborative attuali, non c'Š nessun problema fino al livello 4 compreso. I sorgenti del gioco possono essere inseriti in un file di nome Othello.java e sono riportati di seguito. /************************************ * * * Gioco dell'Othello * * * * di Marco Bertacca * * * ************************************/ import java.awt.*; import java.awt.event.*; import java.applet.Applet; /** * Questa classe rappresenta la scacchiera del gioco dell'othello. * Essa si occupa di accettare le mosse, verificarle e memorizzare * la situazione derivante da esse. * * @version 1.00 97/08/11 * @author Marco Bertacca */ class Scacchiera { /** * Larghezza della scacchiera espressa in numero di celle */ static final int LARGHEZZA = 8; /** * Altezza della scacchiera espressa in numero di celle */ static final int ALTEZZA = 8; /** * Intero indicante una casella vuota */ static final int VUOTO = -1; /** * Intero indicante una casella occupata da una pedina bianca */ static final int BIANCO = 0; /** * Intero indicante una casella occupata da una pedina bianca */ static final int NERO = 1; /** * Indice dell'elemento dell'array che riporta il punteggio posizionale * */ static final int POSIZIONALE = 0; /** * Indice dell'elemento dell'array che riporta il numero di pedine girate * */ static final int PEDINE = 1; /** * Matrice del punteggio di ogni casella racchiusa * * @see #aggiorna */ private static final int puntiInterni[][] ={ { 50, 50, 50, 50, 50, 50, 50, 50 }, { 50, 0, 0, 0, 0, 0, 0, 50 }, { 50, 0, 20, 10, 10, 20, 0, 50 }, { 50, 0, 10, 20, 20, 10, 0, 50 }, { 50, 0, 10, 20, 20, 10, 0, 50 }, { 50, 0, 20, 10, 10, 20, 0, 50 }, { 50, 0, 0, 0, 0, 0, 0, 50 }, { 50, 50, 50, 50, 50, 50, 50, 50 } }; /** * Matrice del punteggio di ogni casella racchiudente * * @see #aggiorna */ private static final int puntiEsterni[][] ={ { 800, -20, 20, 20, 20, 20,-20, 800 }, { -20,-400,-40,-20,-20,-40,-400,-20 }, { 20, -40, 20, 0, 0, 20, -40, 20 }, { 20, -20, 0, 0, 0, 0, -20, 20 }, { 20, -20, 0, 0, 0, 0, -20, 20 }, { 20, -40, 20, 0, 0, 20, -40, 20 }, { -20,-400,-40,-20,-20,-40,-400,-20 }, { 800, -40, 20, 20, 20, 20, -20,800 } }; /** * Matrice per individuare velocemente le posizioni intorno a * una casella data */ private static final int intorno[][] = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 }, { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 } }; /** * Array contenente le pedine della scacchiera */ private int tavola[][]; /** * Costruisce una scacchiera con le pedine per iniziare * una nuova partita. * * @see #reset */ Scacchiera() { reset(); } /** * Costruisce una scacchiera copiando lo stato da quella passata * come argomento. */ Scacchiera(Scacchiera s) { int y; tavola = (int[][]) s.tavola.clone(); for (y = 0; y < ALTEZZA; y++) tavola[y] = (int[]) s.tavola[y].clone(); } /** * Inizializza la scacchiera alle condizioni iniziali */ void reset () { int y, x; tavola = new int[ALTEZZA][LARGHEZZA]; for (y = 0; y < ALTEZZA; y++) for (x = 0; x < LARGHEZZA; x++) tavola[y][x] = VUOTO; tavola[ALTEZZA / 2][LARGHEZZA / 2] = BIANCO; tavola[ALTEZZA / 2 - 1][LARGHEZZA / 2 - 1] = BIANCO; tavola[ALTEZZA / 2][LARGHEZZA / 2 - 1] = NERO; tavola[ALTEZZA / 2 - 1][LARGHEZZA / 2] = NERO; } /** * Restituisce la pedina a riga y e colonna x */ int pedinaA(int y, int x) { if (y >= 0 && y < ALTEZZA && x >= 0 && x < LARGHEZZA) return tavola[y][x]; else return VUOTO; } /** * Aggiorna la scacchiera in conseguenza dell'inserimento di una pedina * nella posizione indicata da y e x e col colore indicato. * @param colore colore della pedina da porre * @param y riga su cui porre la pedina * @param x colonna su cui porre la pedina * @param punteggio pone in punteggio[POSIZIONALE] una valutuzione posizionale * della mossa e in punteggio[PEDINE] il numero di pedine girate */ void aggiorna(int colore, int y,int x, int punteggio[]) { int nY, nX; int i; boolean gira; int altroColore = colore == BIANCO ? NERO : BIANCO; punteggio[POSIZIONALE] = puntiEsterni[y][x]; punteggio[PEDINE] = 0; tavola[y][x] = colore; for (i = 0; i < 8; i++) { nY = y + intorno[i][0]; nX = x + intorno[i][1]; if (nY >= 0 && nY < ALTEZZA && nX >= 0 && nX < LARGHEZZA && tavola[nY][nX] == altroColore) { gira = false; nY += intorno[i][0]; nX += intorno[i][1]; for ( ; nY >= 0 && nY < ALTEZZA && nX >= 0 && nX < LARGHEZZA; nY += intorno[i][0], nX += intorno[i][1]) { if (tavola[nY][nX] == colore) { gira = true; break; } else if (tavola[nY][nX] == VUOTO) break; } if (gira) { nY = y + intorno[i][0]; nX = x + intorno[i][1]; for ( ; nY >= 0 && nY < ALTEZZA && nX >= 0 && nX < LARGHEZZA; nY += intorno[i][0], nX += intorno[i][1]) { if (tavola[nY][nX] == altroColore) { tavola[nY][nX] = colore; punteggio[POSIZIONALE] += puntiInterni[nY][nX]; punteggio[PEDINE]++; } else break; } } } } } /** * Restituisce true se Š ammesso porre una pedina nella posizione * specificata, false altrimenti. * * @param colore colore della pedina da porre * @param y riga su cui porre la pedina * @param x colonna su cui porre la pedina */ boolean ŠValida(int colore, int y,int x) { boolean Return = false; int nY, nX; int i; int altroColore = colore == BIANCO ? NERO : BIANCO; if (y >= 0 && y < ALTEZZA && x >= 0 && x < LARGHEZZA && tavola[y][x] == VUOTO && (colore == BIANCO || colore == NERO)) for (i = 0; i < 8 && !Return; i++) { nY = y + intorno[i][0]; nX = x + intorno[i][1]; if (nY >= 0 && nY < ALTEZZA && nX >= 0 && nX < LARGHEZZA) { if (tavola[nY][nX] == altroColore) { nY += intorno[i][0]; nX += intorno[i][1]; for ( ; nY >= 0 && nY < ALTEZZA && nX >= 0 && nX < LARGHEZZA; nY += intorno[i][0], nX += intorno[i][1]) { if (tavola[nY][nX] == colore) { Return = true; break; } else if (tavola[nY][nX] == VUOTO) break; } } } } return Return; } /** * Se Š ammesso porre una pedina nella posizione specificata, * la pedina viene posta e viene restituito true, * altrimenti viene restituito false. * * @param colore colore della pedina da porre * @param y riga su cui porre la pedina * @param x colonna su cui porre la pedina */ boolean mettiPedina(int colore, int y, int x) { boolean Return; int punteggio[] = { 0, 0 }; if (Return = ŠValida (colore, y, x)) aggiorna (colore, y, x, punteggio); return Return; } /** * Restituisce il numero di pedine vuote sulla scacchiera. * L'array di due elementi fornito come argomento viene riempito * con il numero di pedine bianche e nere. * @param colore array di due elementi il cui elemento colore[BIANCO] * viene riempito col numero di pedine bianche mentre l'elemento * colore[NERO] viene riempito col numero di pedine nere * @return il numero di caselle vuote */ int punti (int colore[]) { int y, x; int Return = colore[BIANCO] = colore[NERO] = 0; for (y = 0; y < ALTEZZA; y++) for (x = 0; x < LARGHEZZA; x++) if (tavola[y][x] == BIANCO) colore[BIANCO]++; else if (tavola[y][x] == NERO) colore[NERO]++; else Return++; return Return; } } /** * Questa classe rappresenta un giocatore di othello. * * @version 1.00 97/08/11 * @author Marco Bertacca */ class Computer { /** * L'oggetto scacchiera su cui giocare */ private Scacchiera scacchiera; /** * Il colore associato al giocatore */ private int colore; /** * Il livello di gioco */ private int livello; /** * Variabile usata per eseguire il numero di ricorsioni pari al livello * di gioco. */ private int livelloTemp; /** * Flag per stabilire quando il gioco Š nella fase finale */ private boolean finale; /** * Contiene il numero di mosse da giocare nella fase finale */ private int finaleDa; /** * Costruisce un'istanza * * @param sc scacchiera su cui giocare * @param co colore assegnato all'istanza * @param li livello di gioco. */ Computer (Scacchiera sc, int co, int li) { scacchiera = sc; colore = co; livello = li; if (livello < 4) finaleDa = 2 * livello + 2; else finaleDa = 10; } /** * Sollecita una mossa. * * @return true se la mossa viene eseguita, * false se non ci sono mosse possibili */ boolean muovi () { int x, y; int mx = -1, my = -1; int punteggio[] = { 0, 0 }; int valore, maxValore = Integer.MIN_VALUE; if (scacchiera.punti(punteggio) < finaleDa) finale = true; else finale = false; for (y = 0; y < 8; y++) for (x = 0; x < 8; x++) if (scacchiera.ŠValida (colore, y, x)) { livelloTemp = 0; valore = valutaMossa (colore, y, x, scacchiera); if (valore > maxValore) { maxValore = valore; mx = x; my = y; } } if (mx >= 0) { scacchiera.mettiPedina (colore, my, mx); return true; } else return false; } /** * Esegue una valutazione della mossa. Questo metodo richiama se stesso * per un numero di volte pari al numero del livello meno 1 * * @param colore colore della pedina da porre * @param y riga su cui porre la pedina * @param x colonna su cui porre la pedina * @param sc scacchiera su cui valutare la mossa * @return un intero corrispondente alla bont… della mossa */ private int valutaMossa (int colore, int y, int x, Scacchiera sc) { int Return; int nX, nY; int punteggio[] = { 0, 0 }; int punti; int altroPuntiTmp, altroPuntiMax; int altroColore = colore == Scacchiera.BIANCO ? Scacchiera.NERO : Scacchiera.BIANCO; Scacchiera scLocale = new Scacchiera(sc); scLocale.aggiorna (colore, y, x, punteggio); if (finale) punti = punteggio[Scacchiera.PEDINE]; else punti = punteggio[Scacchiera.PEDINE] + punteggio[Scacchiera.POSIZIONALE]; if ((y == 0 || y == 7 || x == 0 || x == 7)) punti += valutaBordi(y, x, colore, scLocale); if (++livelloTemp < livello || finale) { altroPuntiMax=-10000; for (nY=0; nY < 8; nY++) for (nX = 0; nX < 8; nX++) if (scLocale.ŠValida (altroColore, nY, nX )) { altroPuntiTmp = valutaMossa(altroColore, nY, nX, scLocale); if ( altroPuntiTmp > altroPuntiMax ) altroPuntiMax = altroPuntiTmp; } punti -= altroPuntiMax; } --livelloTemp; return punti; } /** * Valuta la bont… di una mossa sul bordo della scacchiera. * * @param y riga su cui porre la pedina * @param x colonna su cui porre la pedina * @param colore colore della pedina da porre * @param sc scacchiera su cui valutare la mossa * @return un intero corrispondente alla bont… della mossa */ private int valutaBordi (int y, int x, int colore, Scacchiera sc) { int Return = 0; int altroColore = colore == Scacchiera.BIANCO ? Scacchiera.NERO : Scacchiera.BIANCO; int pedinaSx = Scacchiera.VUOTO; int pedinaDx = Scacchiera.VUOTO; if (y == 0 || y == 7) { if (x == 0 || x == 7) Return = 100; else { pedinaSx = sc.pedinaA (y, x - 1); pedinaDx = sc.pedinaA (y, x + 1); } if (pedinaSx == altroColore && pedinaDx == altroColore) Return = 100; else if (pedinaSx==Scacchiera.VUOTO && pedinaDx==Scacchiera.VUOTO && (x - 2 >= 0 && sc.pedinaA (y, x - 2) == colore || x + 2 < 8 && sc.pedinaA (y, x + 2) == colore)) Return = -10; if (pedinaSx == Scacchiera.VUOTO) { do { if (pedinaDx == Scacchiera.VUOTO) break; if (pedinaDx == altroColore) { Return -= 100; break; } x++; } while (x < 8); } if (pedinaSx == altroColore) { do { if (pedinaDx == altroColore) break; if (pedinaDx == Scacchiera.VUOTO) { Return -= 100; break; } x++; } while (x < 8); } if (pedinaDx == Scacchiera.VUOTO) { do { if (pedinaSx == Scacchiera.VUOTO) break; if (pedinaSx == altroColore) { Return -= 100; break; } x--; } while (x >= 0); } if (pedinaDx == altroColore) { do { if (pedinaSx == altroColore) break; if (pedinaSx == Scacchiera.VUOTO) { Return -= 100; break; } x--; } while (x >= 0); } } else if (x == 0 || x == 7) { pedinaSx = sc.pedinaA (y - 1, x); pedinaDx = sc.pedinaA (y + 1, x); if (pedinaSx == altroColore && pedinaDx == altroColore) Return = 100; else if (pedinaSx==Scacchiera.VUOTO && pedinaDx==Scacchiera.VUOTO && (y - 2 >= 0 && sc.pedinaA (y - 2, x) == colore || y + 2 < 8 && sc.pedinaA (y + 2, x) == colore)) Return = -10; if (pedinaSx == Scacchiera.VUOTO) { do { if (pedinaDx == Scacchiera.VUOTO) break; if (pedinaDx == altroColore) { Return -= 100; break; } y++; } while (y < 8); } if (pedinaSx == altroColore) { do { if (pedinaDx == altroColore) break; if (pedinaDx == Scacchiera.VUOTO) { Return -= 100; break; } y++; } while (y < 8); } if (pedinaDx == Scacchiera.VUOTO) { do { if (pedinaSx == Scacchiera.VUOTO) break; if (pedinaSx == altroColore) { Return -= 100; break; } y--; } while (y >= 0); } if (pedinaDx == altroColore) { do { if (pedinaSx == altroColore) break; if (pedinaSx == Scacchiera.VUOTO) { Return -= 100; break; } y--; } while (y >= 0); } } return Return; } } /** * Questa classe rappresenta l'interfaccia grafica per giocare a othello. * Essa accetta le mosse dall'utente e sollecita le mosse del computer. * * @see java.applet.Applet * @version 1.00 97/08/11 * @author Marco Bertacca */ public class Othello extends Applet implements Runnable, MouseListener { /** * Larghezza di una cella della scacchiera in pixel */ private int larghCella; /** * Altezza di una cella della scacchiera in pixel */ private int altCella; /** * Larghezza totale */ private int larghezza; /** * Altezza totale */ private int altezza; /** * Colore assegnato al giocatore umano */ private int colore; /** * Colore assegnato al computer */ private int altroColore; /** * Flag che indica se il giocatore umano deve passare */ private boolean passa = false; /** * Flag che indica quando il computer sta elaborando una mossa */ private boolean muoveComputer = false; /** * Scacchiera di gioco */ private Scacchiera scac; /** * Il giocatore computer */ private Computer comp; /** * Livello di gioco */ private int livello = 4; /** * Stringa per fornire informazioni al giocatore umano */ private String lineaStato; /** * Font usato per visualizzare le informazioni */ private Font font = new Font("Courier", Font.PLAIN, 12); /** * Altezza del font usato per visualizzare le informazioni */ private int altezzaFont; /** * Effettua l'inizializzazione dell'applet */ public void init() { int livn; String livs = getParameter ("livello"); if (livs != null) { livn = new Integer(livs).intValue(); if (livn > 0 && livn < 9) livello = livn; } altezzaFont = getFontMetrics(font).getHeight(); Dimension d = getSize(); larghCella = d.width / 8; altCella = (d.height - altezzaFont) / 8; larghezza = larghCella * 8; altezza = altCella * 8; lineaStato = "Othello livello: " + livello; scac = new Scacchiera(); comp = new Computer (scac, Scacchiera.NERO, livello); colore = Scacchiera.BIANCO; altroColore = Scacchiera.NERO; addMouseListener (this); } /** * Disegna la scacchiera e le informazioni per l'utente */ public void paint (Graphics g) { int i, j; Color oldColor = g.getColor(); g.setColor (new Color (0, 128, 0)); g.fillRect (0, 0, larghezza, altezza); g.setColor (Color.black); for (i = 0; i < 9; i++) g.drawLine (0, i * altCella, larghezza, i * altCella); for (i = 0; i < 9; i++) g.drawLine (i * larghCella, 0, i * larghCella, altezza); for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) { switch(scac.pedinaA(i, j)) { case Scacchiera.BIANCO: g.setColor (Color.white); g.fillOval (j * larghCella + 1, i * altCella + 1, larghCella - 1, altCella - 1); break; case Scacchiera.NERO: g.setColor (Color.black); g.fillOval (j * larghCella + 1, i * altCella + 1, larghCella - 1, altCella - 1); break; } } g.setFont(font); g.setColor (Color.black); g.drawString (lineaStato, 0, altezza + altezzaFont); } /** * Valuta se esiste una mossa possibile per una pedina * del colore specificato */ private boolean esisteMossa(int col) { int y, x; for (y = 0; y < Scacchiera.ALTEZZA; y++) for (x = 0; x < Scacchiera.LARGHEZZA; x++) if (scac.ŠValida (col, y, x)) return true; return false; } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } /** * In base alla posizione del mouse, ricava la mossa del giocatore umano. * Se il gioco Š gi… finito, fa iniziare una nuova partita. * Se siamo alla prima mossa e la mossa del giocatore umano non Š valida, * passa la mossa al computer. * Se la mossa Š valida, aggiorna la scacchiera e se a quel punto il gioco Š * finito, visualizza i risultati, altrimenti attiva un thread per * l'elaborazione della mossa del computer. */ public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); int punteggio[] = { 0, 0 }; if (!muoveComputer) { if (!esisteMossa(colore) && !esisteMossa(altroColore)) { scac.reset(); lineaStato = "Othello livello: " + livello; repaint(); } else if (passa||scac.mettiPedina(colore,y/altCella,x/larghCella)) { if (!esisteMossa(colore) && !esisteMossa(altroColore)) stampaPunteggio(); else { muoveComputer = true; Thread t = new Thread(this); t.start (); lineaStato = "Sto pensando ..."; repaint(); } } else if (scac.punti (punteggio) == 60) { muoveComputer = true; Thread t = new Thread(this); t.start (); lineaStato = "Sto pensando ..."; repaint(); } } } /** * Sollecita una mossa del computer. */ public void run() { comp.muovi(); passa = false; if (!esisteMossa(colore)) if (!esisteMossa(altroColore)) stampaPunteggio(); else { lineaStato = "Devi passare: clicka"; passa = true; } else lineaStato = "Tocca a te"; repaint(); muoveComputer = false; } /** * Visualizza il punteggio finale di una partita. */ void stampaPunteggio () { int punteggio[] = { 0, 0 }; scac.punti (punteggio); if (punteggio[Scacchiera.BIANCO] > punteggio[Scacchiera.NERO]) lineaStato = "Hai vinto " + punteggio[Scacchiera.BIANCO] + " a " + punteggio[Scacchiera.NERO]; else if (punteggio[Scacchiera.BIANCO] < punteggio[Scacchiera.NERO]) lineaStato = "Hai perso " + punteggio[Scacchiera.BIANCO] + " a " + punteggio[Scacchiera.NERO]; else lineaStato = "Hai pareggiato " + punteggio[Scacchiera.BIANCO] + " a " + punteggio[Scacchiera.NERO]; passa = false; repaint(); } } Per eseguire l'applet si pu• ricorrere a un testo in formato HTML come il seguente Othello

Il livello di gioco viene impostato tramite il parametro livello e per default Š 4. Il programma Š formato da tre sole classi: Othello, che deriva da Applet e si occupa dell'interazione con l'utente, Computer, che elabora le mosse del computer e infine Scacchiera, che rappresenta appunto la scacchiera del gioco. Si pu• notare come la valutazione della mossa del computer sia eseguita da un thread indipendente in modo tale da permettere il ridisegno della scacchiera senza dover aspettare il termine dell'elaborazione della mossa. Il metodo repaint infatti non causa l'immediato ridisegno della finestra, ma segnala solo una necessit…, a cui il sistema risponde appena possibile. I tempi di valutazione della mossa sono quasi impercettibili se il livello Š basso ma crescono vertiginosamente al crescere del livello. Per capirne il perch‚, vediamo come fa il computer a generare una mossa. La classe Scacchiera comprende il metodo ŠValida che permette di valutare se una mossa Š valida o meno, e il metodo aggiorna che, oltre ad accettare una mossa e a modificare la scacchiera di conseguenza, restituisce anche una valutazione sulla sua validit…. Questa valutazione Š espressa da due numeri, uno dei quali rappresenta semplicemente il numero di pedine convertite mentre l'altro corrisponde a una valutazione strategica basata su due matrici, puntiInterni e puntiEsterni. Ogni volta che il computer deve muovere, viene invocato il metodo muovi nel quale vengono riconosciute le mosse valide tramite il metodo ŠValida e per ognuna di esse viene invocato il metodo valutaMossa passandogli come argomento anche l'oggetto della classe Scacchiera che rappresenta la scacchiera corrente, vedi figura B.2. Quest'ultimo metodo si crea una scacchiera temporanea identica a quella passata come argomento e su di essa applica la mossa in valutazione, ricavando in tal modo un punteggio che ne indica la validit…. Se stiamo giocando al livello 1, questo valore viene direttamente restituito al metodo muovi che alla fine premier… la mossa col punteggio maggiore. Giocando al livello 2 invece vengono valutate tutte le mosse che possono derivare dalla mossa in esame e il punteggio pi— alto viene sottratto a quello della mossa in esame. Giocando a livello n vengono valutati quindi n livelli di mosse e contro mosse, dando luogo a un'esplosione combinatoria di valutazioni che rapidamente satura la potenza d'elaborazione di un computer. Il procedimento pu• apparire complicato ma invece diventa di semplice implementazione utilizzando la ricorsione. Figura B.2 E' in corso la valutazione delle possibili mosse valide Per migliorare la capacit… di gioco del calcolatore, Š stato aggiunto il metodo valutaBordi per compensare la valutazione delle mosse effettuate sul bordo. Oltre a questo, quando si arriva al finale del gioco, il computer valuta in modo esaustivo tutte le mosse che rimangono basando a questo punto il proprio giudizio solo sul numero di pedine convertite.