MokaByte
Numero 19 - Maggio 1998
|
|||
|
struttura Client Server |
||
Dario Bosi |
|
||
INTRODUZIONE
L'idea di questo
articolo mi e' venuta leggendo le numerose lettere sulla mailing list JAVA-IT
che trattano l'accesso ai Database.
Pur sapendo
di affrontare argomenti gia' in parte trattati da altri collaboratori,
mi e' sembrato utile fornire un esempio completo.
Il lavoro si
compone di 2 parti:
- Una applicazione
che gira sul server.
- Un applet
che puo' essere scaricato dal server attraverso Internet.
Il client ed
il server comunicano tra loro attraverso un socket.
Il socket viene
aperto sulla porta 5060. Si puo' usare qualunque altra porta non occupata
diversamente.
La comunicazione
avviene con i metodi readLine e println.
Per migliorare
le prestazioni si inviano sul socket piu' dati contemporaneamente, separati
da un opportuno delimitatore.
In ricezione
i singoli dati vengono ritrovati usando StringTokenizer.
APPLICAZIONE
SERVER:
Il server e'
stato testato in Windows NT con il JDK 1.1.3 ma dovrebbe funzionare anche
sotto Unix e con tutti i JDK 1.1.x.
Esso comunica
con il database attrverso il ponte JDBC-ODBC.
Per motivi legati
alla sicurazza, il programma server deve girare sulla stessa macchina da
cui viene scricato l'applet.
Il server e'
provvisto di un batch di partenza. Il batch contiene il riferimento al
classpath, e quindi deve essere modificato a seconda di come e' installato
il JDK.
Inoltre sulla
linea di comando bisogna indicare la fonte ODBC dei dati.
Ad esempio,
se la fonte dei dati si chiama archivio, la linea di comando da digitare
sara':
server archivioIl server usa un'interfaccia a caratteri, e quindi puo' essere utilizzato anche su sistemi non grafici.
APPLET CLIENT:
Il client usa
il JDK 1.0.2 ed e' stato testato sotto Windows sia con Netscape che con
MS Explorer.
Esso genera
una frame di 780x515 pixel, e quindi richiede uno schermo almeno 800x600.
Anzitutto il client tenta di collegarsi al server per controllare che sia attivo. Se non e' attivo non consente di proseguire.
Sono possibili 4 diverse operazioni:
1 - La visualizzazione
dell'intero archivio su una listbox.
2 - La modifica
di un record.
3 - La cancellazione
di un record
4 - L'aggiunta
di nuovi record.
Le funzioni 1 e 4 sono sulla videata iniziale, mentre alla 2 e alla 3 si accede con doppio click sulla listbox.
Il campo codice, che funge da chiave, e' di tipo autoinc e viene assegnato dal server.
ARCHIVIO:
L'archivio di
prova e' stato testato in formato access.
Bisogna anzitutto
settare ODBC in modo che l'archivio diventi una fonte di dati ODBC. (Su
windows usare Pannello di Controllo - ODBC).
La struttura dell'archivio e' la seguente:
TABELLA: personeLIMITAZIONI:
CAMPI: codice:----numerico autoinc
cognome:---18 caratteri
nome:------18 caratteri
indirizzo:-25 caratteri
citta:-----20 caratteri
telefono:--14 caratteri
BATCH DI PARTENZA DELL'APPLICAZIONE SERVER
\jdk113\bin\java -classpath .;c:\jdk113\lib\classes.zip;c:\jdk113\java\lib Server %1SEGUONO I SORGENTI COMMENTATI DELL'APPLICAZIONE SERVER E DELL'APPLET CLIENT.
// *******************************************************************
// * APPLICAZIONE SERVER *
// * IL NOME DELLA FONTE ODBC VIENE PASSATO SULLA LINEA DI COMANDO *
// *******************************************************************import java.util.*;
import java.io.*;
import java.sql.*;
import java.net.*;
import java.text.*;public class Server {
// La variabile nconn e' il numero di connessioni (socket) aperte.
// E' definita static perche' viene aggiornata dalla classe ServerThread
static int nconn = 0;
// il metodo incnoconn viene chiamato per incrementare la variabile nconn
static synchronized int incnconn()
{
++nconn;
return nconn;
}
// il metodo incnoconn viene chiamato per decrementare la variabile nconn
static synchronized int decnconn()
{
--nconn;
return nconn;
}// COSTRUTTORE DI CLASSE DEL PROGRAMMA PRINCIPALE
public static void main(String[] args) {
ServerSocket serverSocket = null;
String NDB;
String sockdat;
Database database;
boolean listening = true;
int port=5060;
int numconn;// LEGGO LA FONTE DEI DATI DALLA LINEA DI COMANDO
// deve essere il nome di una fonte odbc disponibile sul computer
if (args.length != 1) {
System.err.println("Errore sulla linea di comando");
System.exit(-1);
return;
}
NDB = args[0];
// DETERMINO IL NOME DEL SERVER LOCALE
// serve solo per documentazione al lancio del programma
try {
InetAddress indilocal = InetAddress.getLocalHost();
System.err.println("NOME DI QUESTO SERVER: "+indilocal.toString());
System.err.println("Per terminare il programma digitare il tasto f seguito da Invio.");
}
catch (IOException e) {
System.err.println(e);
}// APRO UN SERVERSOCKET SULLA PORTA 5060
// il client dovra aprire il socket sulla stessa porta.
try {
serverSocket = new ServerSocket(port);
}
catch (IOException e) {
System.err.println("Non posso usare la porta " + port + ", " + e.getMessage());
System.exit(1);
}// Creo SINGOLA Istanza del Database
// tutte le connessioni si appoggiano ad un unico oggetto database
// NDB e' la fonte dei dati.
database = new Database("jdbc:odbc:"+NDB);// acquisizione da tastiera del segnale di fine programma
// devo fare un Thread separato, altrimenti blocca il programma.
new FineThread(database).start();// Esegue un ciclo infinito.
// Ogni volta che un utente si collega lancio un Thread per gestirne le richieste.
while (listening) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(3600000); //SE IL SOCKET RESTA INATTIVO PER 1 ORA LO CHIUDO
numconn = Server.incnconn();
// Stampo sullo schermo del server il numero di connessioni aperte.
System.out.println("Ho aperto un socket. Connessioni in uso: "+String.valueOf(numconn));
}
catch (InterruptedIOException IOe) {
try {
clientSocket.close();
System.err.println("Socket chiuso per timeout "+IOe.getMessage());
}
catch (IOException ex3) {
System.err.println("Close fallito. "+ex3.getMessage());
}
continue;
}
catch (IOException e) {
System.err.println("Socket non accettato: "+port+", "+e.getMessage());
continue;
}
new ServerThread(clientSocket, database).start();
}
}
}
// ************************************************************/
// * Definisco la classe Database che accede al Database e */
// * mi esegue le operazioni di accesso, connessione, query e */
// * update */
// ************************************************************/class Database {
Connection dbconn;
//Il COSTRUTTORE DI CLASSE mi esegue la connessione al database
public Database(String URL) {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException ex2) {
System.err.println("Fallita connessione al database. Errore 1");
System.exit(-1);
}
catch (Exception ex) {
System.err.println("Fallita connessione al database. Errore 2");
ex.printStackTrace();
System.exit(-1);
}
try {
dbconn = DriverManager.getConnection(URL);
}
catch (SQLException e) {
System.err.println("Fallita connessione al database.. Errore 3");
System.err.println("La fonte ODBC non esiste.");
System.exit(-1);
}
catch (Exception ex) {
System.err.println("Fallita connessione al database. Errore 4");
ex.printStackTrace();
System.exit(-1);
}
}//Il metodo ESEGUI_QUERY esegue un comando SQL (select) sul database
//sottostante e ritorna un Result_Set al chiamante;
public synchronized ResultSet Esegui_Query(String stringa_SQL) {
Statement statement;
ResultSet result_set = null;
ResultSetMetaData meta_data;
try {
statement = dbconn.createStatement();
result_set = statement.executeQuery(stringa_SQL);
//statement.close(); //NON USARE FORSE C'E' UN BUG ??
}
catch (SQLException e) {
System.err.println(e.getMessage());
System.err.println(e.getErrorCode());
System.exit(1);
}
return result_set;
}//Il metodo ESEGUI_UPDATE esegue un comando SQL (Update o Delete) sul database
//sottostante e ritorna il numero di righe modificate o cancellate al chiamante;
public synchronized int Esegui_Update (String stringa_SQL) {
Statement statement;
int NumRighe = 0;
try {
statement = dbconn.createStatement();
NumRighe = statement.executeUpdate(stringa_SQL);
statement.close();
}
catch (SQLException e) {
System.err.println(e.getMessage());
System.err.println(e.getErrorCode());
}
return NumRighe;
}//Il metodo DBCCHIUDI esegue la commit e chiude la connessione al Database
//In questo esempio non viene usato
public void dbchiudi() {
try {
dbconn.commit();
dbconn.close();
}
catch (SQLException e) {
System.err.println(e.getMessage());
System.err.println(e.getErrorCode());
}
}}
// *************************************
// * CREO LA CLASSE SERVERTHREAD *
// *************************************
class ServerThread extends Thread {
Database database;
Socket socket;
int i,numconn;
// campi del database
String campo1,campo2,campo3,campo4,campo5,campo6;
// COSTRUTTORE DI CLASSE
ServerThread(Socket sock, Database DB) {
super("ServerThread");
this.socket = sock;
this.database = DB;
}public void run() {
String tmp,inputriga;
StringTokenizer tokens, token2;
boolean transacting = true;
//consultazione
ResultSet RScons,RScodice;
String riscons;
// risultato delle update
int rigupdate;
//INIZIO
try {
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(),true);
try {
output.println("Welcome");
}
catch (Exception e) {
System.err.println ("Welcome Failed");
}
// ciclo infinito
// Ogni volte che riceve una parola chiave ( consulta inserisci ecc.. )
// il server intraprende l'azione opportuna
// La comunicazione avviene con i metodi readLine e println
// Per migliorare le prestazioni si inviano sul socket piu' dati contemporaneamente,
// separati da un delimitatore.
// In ricezione i singoli dati vengono ritrovati usando StringTokenizer
while (transacting) {
inputriga = input.readLine();
tokens = new StringTokenizer(inputriga, "#");
tmp = tokens.nextToken();// CONSULTAZIONE
if (tmp.equals("consulta")) {
RScons=database.Esegui_Query("SELECT * FROM PERSONE");
riscons="";
while (RScons.next()) {
campo1=preptr(RScons.getString(1));
campo2=preptr(RScons.getString(2));
campo3=preptr(RScons.getString(3));
campo4=preptr(RScons.getString(4));
campo5=preptr(RScons.getString(5));
campo6=preptr(RScons.getString(6));
// ciascun campo e' separato da $
// ciascun record e' separato da #if (riscons.equals("")) {
riscons+=campo1+"§"+campo2+"§"+campo3+"§"+campo4+"§"+campo5+"§"+campo6;
}
else {
riscons+="#"+campo1+"§"+campo2+"§"+campo3+"§"+campo4+"§"+campo5+"§"+campo6;
}
}
// Riscons contiene l'intero Database.
// Naturalmente questo e' accettabile solo per database "piccoli".
if (riscons.equals("")) {
riscons="null";
}
output.println(riscons);
}// AGGIORNAMENTO
if (tmp.equals("memorizza")) {
campo1 = tokens.nextToken();
campo2 = tokens.nextToken();
campo3 = tokens.nextToken();
campo4 = tokens.nextToken();
campo5 = tokens.nextToken();
campo6 = tokens.nextToken();
// rigupdate e' il numero di righe modificate dalla Update
rigupdate=database.Esegui_Update("UPDATE PERSONE SET COGNOME = '"+campo2+"', NOME = '"+campo3+"', INDIRIZZO = '"+campo4+"', CITTA = '"+campo5+"', TELEFONO = '"+campo6+"' WHERE ( CODICE = "+campo1+" ) ");
// Se dico OK al client vuol dire che l'operazione e' andata a buon fine.
if (rigupdate>0) {
output.println("OK");
}
else {
output.println("KO");
}
}// INSERIMENTO
if (tmp.equals("inserisci")) {
campo2 = tokens.nextToken();
campo3 = tokens.nextToken();
campo4 = tokens.nextToken();
campo5 = tokens.nextToken();
campo6 = tokens.nextToken();
rigupdate=database.Esegui_Update("INSERT INTO PERSONE (COGNOME, NOME, INDIRIZZO, CITTA, TELEFONO ) VALUES ('"+campo2+"', '"+campo3+"', '"+campo4+"', '"+campo5+"', '"+campo6+"')");
if (rigupdate>0) {
// Il codice e' scelto dal database (autoinc)
// Trasmetto al client il codice del nuovo record
RScodice=database.Esegui_Query("SELECT MAX(CODICE) FROM PERSONE ");
while (RScodice.next()) {
campo1 = RScodice.getString(1);
}
output.println(campo1);
}
else {
output.println("KO");
}
}// ELIMINAZIONE RECORD
if (tmp.equals("cancella")) {
campo1 = tokens.nextToken();
rigupdate=database.Esegui_Update("DELETE FROM PERSONE WHERE ( CODICE = "+campo1+" ) ");
if (rigupdate>0) {
output.println("OK");
}
else {
output.println("KO");
}
}} // while (transacting)
} // try
catch (Exception e) {
}
// la finally viene eseguita quando l'utente chiude il socket
finally {
try {
socket.close();
numconn=Server.decnconn();
// Stampo sullo schermo del server il numero di connessioni aperte.
System.out.println("Ho chiuso un socket. Connessioni in uso: "+String.valueOf(numconn));
}
catch (IOException e) {
System.err.println("Non posso chiudere il socket " + e.getMessage());
}
} // finally
} // run// Il metodo preptr prepara ciascun campo per la trasmissione
// se il campo e' vuoto bisogna metterci almeno un blank
String preptr(String stxx) {
String retstr;
if (stxx.equals("")) {
retstr=" ";
}
else {
retstr=stxx;
}
return retstr;
}} // ServerThread
// LA CLASSE FINETHREAD SERVE PER TERMINARE REGOLARMENTE IL PROGRAMMA
class FineThread extends Thread {
Database database;
int kkey;
FineThread(Database DB) {
super("FineThread");
this.database=DB;
}
public void run() {
for(;;) {
try {
kkey=System.in.read();
// 70 e 102 sono i codici del tasto f maiuscolo e minuscolo
if((kkey==70)||(kkey==102)) {
database.dbchiudi();
System.exit(0);
}
}
catch (IOException e) {
System.err.println("Errore nella lettura del tasto");
}
}
}
}
// ********************
// * APPLET CLIENT *
// ********************
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;public class Client extends Applet {
String host;
AppletContext apcont;
Mioframe mioframe;
public void init() {
super.init();
apcont = getAppletContext();
// trova l'indirizzo IP da cui viene scaricato l'applet
try {
host = InetAddress.getByName(getDocumentBase().getHost()).getHostAddress();
}
catch (java.net.UnknownHostException e) {
System.err.println("errore InetAddress");
}
}
public synchronized void start() {
mioframe = new Mioframe("ESEMPIO CLIENT-SERVER PER ACCESSO A DATABASE",host,apcont);
super.start();
}
public synchronized void stop() {
mioframe.dispose();
super.stop();
}
} // fine della classe Client
// ************************
// * CLASSE FINESTRA *
// ************************
class Mioframe extends Frame {
int port=5060;
int ssock;
int numrec;
String host;
String stfineurl;
String tmp="";
AppletContext apcont;
Socket socket;
DataInputStream input;
PrintStream output;
StringTokenizer tokens,token2;
URL fineurl;
// Font grafiche e colori
Font ffont10 = new Font("Courier",Font.PLAIN,10);
Font ffont12 = new Font("Courier",Font.PLAIN,12);
Font ffont14 = new Font("Courier",Font.PLAIN,14);
Font ffont16 = new Font("Courier",Font.PLAIN,16);
Font ffont18 = new Font("Courier",Font.PLAIN,18);
Color bianco = new Color(16777215);
Color giallo = new Color(16776960);
Color azzurro = new Color(65535);
Color verde = new Color(65280);
Color grigiochiaro = new Color(12632256);
Color rosso = new Color(16711680);
Color magenta = new Color(16711935);
// stringhe contenenti campi del record
String strecord,stcodice,stcognome,stnome,stindir,stcitt,sttelef;
// DEFINISCO I COMPONENTI DI CIASCUNA SCHERMATA DELL'APPLET
// PER VISUALIZZARE UNA SCHERMATA RICHIAMO GLI APPOSITI METODI
// CHE ESEGUONO LO SHOW E IL RESHAPE
// pagina 0
Button btnMenucons,btnMenuins,btnFine;
Label lbl00;
// pagina 1 - consulta database
Label lbl10;
List lstCons;
Button btnFinecons;
// pagina 2 - modifica o elimina record
Label lblMod0,lblMod1,lblMod2,lblMod3,lblMod4,lblMod5,lblMod6;
TextField txtMod1,txtMod2,txtMod3,txtMod4,txtMod5,txtMod6;
Button btnRinumod,btnMod,btnDel,btnConfdel;
// pagina 3 - inserisci record
Label lblIns0,lblIns1,lblIns2,lblIns3,lblIns4,lblIns5,lblIns6;
TextField txtIns1,txtIns2,txtIns3,txtIns4,txtIns5,txtIns6;
Button btnRinuins,btnResetins,btnIns;// *****************************
// * COSTRUTTORE DELLA FRAME *
// *****************************
Mioframe(String title, String host, AppletContext apcont) {
super(title);
this.host=host;
this.apcont=apcont;
setLayout(null);
addNotify();
setFont(ffont12);
setBackground(azzurro);
// STURL2 e' l'URL cui si arriva a fine programma. CORRISPONDE ALLA HOME PAGE DEL SERVER.
stfineurl = "http://"+host;// ELEMNTI DELL'INTERFACCIA
// PAGINA 0 - inizio
lbl00 = new Label("");
lbl00.setFont(ffont16);
add(lbl00);
btnMenucons = new Button("Consulta Database");
btnMenucons.setFont(ffont12);
btnMenucons.disable();
add(btnMenucons);
btnMenuins = new Button("Aggiungi Record");
btnMenuins.setFont(ffont12);
btnMenuins.disable();
add(btnMenuins);
btnFine = new Button("Fine programma");
btnFine.setFont(ffont12);
add(btnFine);
// PAGINA 1 - consulta
lbl10 = new Label();
lbl10.setFont(ffont16);
add(lbl10);
lstCons = new List(0,false);
lstCons.setBackground(bianco);
lstCons.setFont(ffont12);
add(lstCons);
btnFinecons = new Button("Fine consultazione");
btnFinecons.setFont(ffont12);
add(btnFinecons);
// PAGINA 2 - modifica
lblMod0 = new Label();
lblMod0.setFont(ffont14);
add(lblMod0);
lblMod1 = new Label("Codice");
lblMod1.setFont(ffont14);
add(lblMod1);
txtMod1 = new TextField();
txtMod1.setFont(ffont14);
txtMod1.setBackground(giallo);
txtMod1.setEditable(false);
add(txtMod1);
lblMod2 = new Label("Cognome");
lblMod2.setFont(ffont14);
add(lblMod2);
txtMod2 = new TextField();
txtMod2.setFont(ffont14);
txtMod2.setBackground(bianco);
add(txtMod2);
lblMod3 = new Label("Nome");
lblMod3.setFont(ffont14);
add(lblMod3);
txtMod3 = new TextField();
txtMod3.setFont(ffont14);
txtMod3.setBackground(bianco);
add(txtMod3);
lblMod4 = new Label("Indirizzo");
lblMod4.setFont(ffont14);
add(lblMod4);
txtMod4 = new TextField();
txtMod4.setFont(ffont14);
txtMod4.setBackground(bianco);
add(txtMod4);
lblMod5 = new Label("Citta'");
lblMod5.setFont(ffont14);
add(lblMod5);
txtMod5 = new TextField();
txtMod5.setFont(ffont14);
txtMod5.setBackground(bianco);
add(txtMod5);
lblMod6 = new Label("Telefono");
lblMod6.setFont(ffont14);
add(lblMod6);
txtMod6 = new TextField();
txtMod6.setFont(ffont14);
txtMod6.setBackground(bianco);
add(txtMod6);
btnRinumod = new Button("Fine");
btnRinumod.setFont(ffont12);
add(btnRinumod);
btnMod = new Button("Memorizza");
btnMod.setFont(ffont12);
add(btnMod);
btnDel = new Button("Elimina Record");
btnDel.setFont(ffont12);
add(btnDel);
btnConfdel = new Button("Elimina Record");
btnConfdel.setFont(ffont12);
add(btnConfdel);
// PAGINA 3 - inserisci
lblIns0 = new Label();
lblIns0.setFont(ffont14);
add(lblIns0);
lblIns1 = new Label("Codice");
lblIns1.setFont(ffont14);
add(lblIns1);
txtIns1 = new TextField();
txtIns1.setFont(ffont14);
txtIns1.setBackground(giallo);
txtIns1.setEditable(false);
add(txtIns1);
lblIns2 = new Label("Cognome");
lblIns2.setFont(ffont14);
add(lblIns2);
txtIns2 = new TextField();
txtIns2.setFont(ffont14);
txtIns2.setBackground(bianco);
add(txtIns2);
lblIns3 = new Label("Nome");
lblIns3.setFont(ffont14);
add(lblIns3);
txtIns3 = new TextField();
txtIns3.setFont(ffont14);
txtIns3.setBackground(bianco);
add(txtIns3);
lblIns4 = new Label("Indirizzo");
lblIns4.setFont(ffont14);
add(lblIns4);
txtIns4 = new TextField();
txtIns4.setFont(ffont14);
txtIns4.setBackground(bianco);
add(txtIns4);
lblIns5 = new Label("Citta'");
lblIns5.setFont(ffont14);
add(lblIns5);
txtIns5 = new TextField();
txtIns5.setFont(ffont14);
txtIns5.setBackground(bianco);
add(txtIns5);
lblIns6 = new Label("Telefono");
lblIns6.setFont(ffont14);
add(lblIns6);
txtIns6 = new TextField();
txtIns6.setFont(ffont14);
txtIns6.setBackground(bianco);
add(txtIns6);
btnRinuins = new Button("Fine");
btnRinuins.setFont(ffont12);
add(btnRinuins);
btnResetins = new Button("Reset");
btnResetins.setFont(ffont12);
add(btnResetins);
btnIns = new Button("Memorizza");
btnIns.setFont(ffont12);
add(btnIns);
// APRO UN SOCKET
ssock=0;
aprisocket();// INIZIO
this.reshape(10,20,780,515);
this.show();
frameresh0();
frameshow0();
}// *********************
// * GESTIONE EVENTI *
// *********************
public boolean handleEvent(Event event) {
// EVENTI DELLA PAGINA 0 - MENU' PRINCIPALE
// Se premo il BOTTONE di CONSULTA DATABASE
if ((event.target==btnMenucons)&&(event.id==Event.ACTION_EVENT)) {
consult();
}
// Se premo il BOTTONE di AGGIUNGI RECORD
if ((event.target==btnMenuins)&&(event.id==Event.ACTION_EVENT)) {
framehide();
lblIns0.setText("INTRODUCI IL NUOVO RECORD");
frameresh3();
frameshow3();
txtIns2.requestFocus();
}
// Se premo il BOTTONE di FINE PROGRAMMA
if ((event.target==btnFine)&&(event.id==Event.ACTION_EVENT)) {
fineprog();
}// EVENTI DELLA PAGINA 1 - LISTA
// Se premo il BOTTONE di FINE CONSULTAZIONE
if ((event.target==btnFinecons)&&(event.id==Event.ACTION_EVENT)) {
framehide();
if (lstCons.countItems()>0) {
lstCons.delItems(0,lstCons.countItems()-1);
}
frameresh0();
frameshow0();
}
// Se premo sulla lista per MODIFICARE IL RECORD
if ((event.target==lstCons)&&(event.id==Event.ACTION_EVENT)) {
modif();
}// EVENTI DELLA PAGINA 2 - MODIFICA
// Se premo IL BOTTONE MEMORIZZA MODIFICA
if ((event.target==btnMod)&&(event.id==Event.ACTION_EVENT)) {
btnMod.disable();
btnDel.disable();
memomod();
}
// Se premo IL BOTTONE ELIMINA RECORD
if ((event.target==btnDel)&&(event.id==Event.ACTION_EVENT)) {
rdelete();
}
// Se premo IL BOTTONE CONFERMA ELIMINAZIONE RECORD
if ((event.target==btnConfdel)&&(event.id==Event.ACTION_EVENT)) {
btnConfdel.disable();
confdel();
}
// Se premo il BOTTONE di FINE MODIFICHE
if ((event.target==btnRinumod)&&(event.id==Event.ACTION_EVENT)) {
framehide();
btnMod.enable();
btnDel.enable();
btnConfdel.enable();
frameresh1();
frameshow1();
}// EVENTI DELLA PAGINA 3 - INSERIMENTO
// Se premo IL BOTTONE AGGIUNGI RECORD
if ((event.target==btnIns)&&(event.id==Event.ACTION_EVENT)) {
btnIns.disable();
memoins();
}
// Se premo il BOTTONE di FINE INSERIMENTI
if ((event.target==btnRinuins)&&(event.id==Event.ACTION_EVENT)) {
framehide();
blanktext(); // mette a blank i campi per l'inserimento
frameresh0();
frameshow0();
}
// Se premo il BOTTONE di RESET INSERIMENTI
if ((event.target==btnResetins)&&(event.id==Event.ACTION_EVENT)) {
lblIns0.setText("INTRODUCI IL NUOVO RECORD");
blanktext(); // mette a blank i campi per l'inserimento
btnIns.enable();
}return super.handleEvent(event);
}// RESHAPE,SHOW E HIDE DELLE FINESTRE
// esegue il resape del menu' principale
void frameresh0() {
lbl00.reshape(20,35,700,30);
btnMenucons.reshape(50,450,150,25);
btnMenuins.reshape(250,450,150,25);
btnFine.reshape(450,450,150,25);
}
// esegue lo show del menu' principale
void frameshow0() {
lbl00.show();
btnMenucons.show();
btnMenuins.show();
btnFine.show();
}
// esegue il reshape della lista archivio
void frameresh1() {
lbl10.reshape(20,30,700,30);
lstCons.reshape(5,70,770,350);
btnFinecons.reshape(450,450,150,25);
}
// esegue lo show della lista archivio
void frameshow1() {
lbl10.show();
lstCons.show();
btnFinecons.show();
}
// esegue il reshape della maschera di modifica record
void frameresh2() {
lblMod0.reshape(30,50,600,30);
lblMod1.reshape(100,100,150,30);
txtMod1.reshape(300,100,300,30);
lblMod2.reshape(100,150,150,30);
txtMod2.reshape(300,150,300,30);
lblMod3.reshape(100,200,150,30);
txtMod3.reshape(300,200,300,30);
lblMod4.reshape(100,250,150,30);
txtMod4.reshape(300,250,300,30);
lblMod5.reshape(100,300,150,30);
txtMod5.reshape(300,300,300,30);
lblMod6.reshape(100,350,150,30);
txtMod6.reshape(300,350,300,30);
btnMod.reshape(70,450,150,25);
btnDel.reshape(250,450,150,25);
btnRinumod.reshape(430,450,150,25);
}
// esegue lo show della maschera di modifica record
void frameshow2() {
lblMod0.show();
lblMod1.show();
txtMod1.show();
lblMod2.show();
txtMod2.show();
lblMod3.show();
txtMod3.show();
lblMod4.show();
txtMod4.show();
lblMod5.show();
txtMod5.show();
lblMod6.show();
txtMod6.show();
btnMod.show();
btnDel.show();
btnRinumod.show();
}
// esegue il reshape della maschera di inserimento record
void frameresh3() {
lblIns0.reshape(30,50,400,30);
lblIns1.reshape(100,100,150,30);
txtIns1.reshape(300,100,300,30);
lblIns2.reshape(100,150,150,30);
txtIns2.reshape(300,150,300,30);
lblIns3.reshape(100,200,150,30);
txtIns3.reshape(300,200,300,30);
lblIns4.reshape(100,250,150,30);
txtIns4.reshape(300,250,300,30);
lblIns5.reshape(100,300,150,30);
txtIns5.reshape(300,300,300,30);
lblIns6.reshape(100,350,150,30);
txtIns6.reshape(300,350,300,30);
btnIns.reshape(70,450,150,25);
btnRinuins.reshape(250,450,150,25);
btnResetins.reshape(430,450,150,25);
}
// esegue lo show della maschera di inserimento record
void frameshow3() {
lblIns0.show();
lblIns1.show();
txtIns1.show();
lblIns2.show();
txtIns2.show();
lblIns3.show();
txtIns3.show();
lblIns4.show();
txtIns4.show();
lblIns5.show();
txtIns5.show();
lblIns6.show();
txtIns6.show();
btnRinuins.show();
btnResetins.show();
btnIns.show();
}
// Esegue la cancellazione di tutti i componenti dello schermo
// Su programmi molto grandi e' meglio avere diverse routine di hide
// per ciascuna videata.
void framehide() {
lbl00.hide();
btnMenucons.hide();
btnMenuins.hide();
btnFine.hide();
lbl10.hide();
lstCons.hide();
btnFinecons.hide();
lblMod0.hide();
lblMod1.hide();
txtMod1.hide();
lblMod2.hide();
txtMod2.hide();
lblMod3.hide();
txtMod3.hide();
lblMod4.hide();
txtMod4.hide();
lblMod5.hide();
txtMod5.hide();
lblMod6.hide();
txtMod6.hide();
btnMod.hide();
btnDel.hide();
btnConfdel.hide();
btnRinumod.hide();
lblIns0.hide();
lblIns1.hide();
txtIns1.hide();
lblIns2.hide();
txtIns2.hide();
lblIns3.hide();
txtIns3.hide();
lblIns4.hide();
txtIns4.hide();
lblIns5.hide();
txtIns5.hide();
lblIns6.hide();
txtIns6.hide();
btnIns.hide();
btnRinuins.hide();
btnResetins.hide();
}// termina il programma
public void fineprog(){
dispose();
try {
fineurl = new URL(stfineurl);
apcont.showDocument(fineurl);
} catch (IOException ex2) {
System.err.println("url errata");
}
}// OVERRIDING DEL METODO DISPOSE - IL SOCKET SI CHIUDE INSIEME ALLA FRAME
public synchronized void dispose() {
chiudisocket();
super.dispose();
}// VISUALIZZA LA LISTA CONTENENTE L'INTERO ARCHIVIO
void consult() {
framehide();
frameresh1();
frameshow1();
lbl10.setText("Attendere ... ");
output.println("consulta");
try {
tmp = input.readLine();
if (tmp.equals("null")) {
lbl10.setText("L'archivio e' vuoto");
}
else {
tokens = new StringTokenizer(tmp,"#");
for (;;) {
try {
token2 = new StringTokenizer(tokens.nextToken(),"§");
lstCons.addItem(aggsp1(token2.nextToken(),6)+aggsp1(token2.nextToken(),19)+aggsp1(token2.nextToken(),19)+aggsp1(token2.nextToken(),26)+aggsp1(token2.nextToken(),21)+aggsp1(token2.nextToken(),14));
lbl10.setText("FAI DOPPIO CLICK SULLA LISTA PER MODIFICARE O ELIMINARE IL RECORD.");
}
catch (NoSuchElementException ex) {
break;
}
}
}
}
catch (java.io.IOException e) {
System.err.println("readLine consult error");
}
lstCons.show();
}// MASCHERA PER MODIFICARE IL RECORD
void modif() {
framehide();
lblMod0.setText("INTRODUCI I NUOVI DATI");
numrec=lstCons.getSelectedIndex();
strecord=lstCons.getItem(numrec);
stcodice=strecord.substring(0,6).trim();
stcognome=strecord.substring(6,24).trim();
stnome=strecord.substring(25,43).trim().trim();
stindir=strecord.substring(44,69).trim();
stcitt=strecord.substring(70,90).trim();
sttelef=strecord.substring(91,105).trim();
txtMod1.setText(stcodice);
txtMod2.setText(stcognome);
txtMod3.setText(stnome);
txtMod4.setText(stindir);
txtMod5.setText(stcitt);
txtMod6.setText(sttelef);
frameresh2();
frameshow2();
}// ESEGUE LA MODIFICA DEL RECORD
void memomod() {
stcognome=prepdb(txtMod2.getText().trim(),14);
stnome=prepdb(txtMod3.getText().trim(),18);
stindir=prepdb(txtMod4.getText().trim(),25);
stcitt=prepdb(txtMod5.getText().trim(),20);
sttelef=prepdb(txtMod6.getText().trim(),14);
output.println("memorizza#"+stcodice+"#"+stcognome+"#"+stnome+"#"+stindir+"#"+stcitt+"#"+sttelef);
try {
tmp = input.readLine();
if (tmp.equals("OK")) {
lblMod0.setText("AGGIORNAMENTO ESEGUITO.");
strecord=aggsp1(stcodice,6)+aggsp1(stcognome,19)+aggsp1(stnome,19)+aggsp1(stindir,26)+aggsp1(stcitt,21)+aggsp1(sttelef,14);
lstCons.replaceItem(strecord,numrec);
txtMod2.setText(stcognome);
txtMod3.setText(stnome);
txtMod4.setText(stindir);
txtMod5.setText(stcitt);
txtMod6.setText(sttelef);
}
else {
lblMod0.setText("ATTENZIONE : AGGIORNAMENTO NON ESEGUITO.");
stcodice=strecord.substring(0,6).trim();
stcognome=strecord.substring(6,24).trim();
stnome=strecord.substring(25,43).trim().trim();
stindir=strecord.substring(44,69).trim();
stcitt=strecord.substring(70,90).trim();
sttelef=strecord.substring(91,105).trim();
txtMod1.setText(stcodice);
txtMod2.setText(stcognome);
txtMod3.setText(stnome);
txtMod4.setText(stindir);
txtMod5.setText(stcitt);
txtMod6.setText(sttelef);
}
}
catch (java.io.IOException e) {
System.err.println("readLine memorizza error");
lblMod0.setText("ATTENZIONE : ERRORE NELL'AGGIORNAMENTO.");
}
}// CHIEDE CONFERMA PRIMA DI ELIMINARE UN RECORD
void rdelete() {
stcognome=strecord.substring(6,24).trim();
stnome=strecord.substring(25,43).trim().trim();
stindir=strecord.substring(44,69).trim();
stcitt=strecord.substring(70,90).trim();
sttelef=strecord.substring(91,105).trim();
txtMod2.setText(stcognome);
txtMod3.setText(stnome);
txtMod4.setText(stindir);
txtMod5.setText(stcitt);
txtMod6.setText(sttelef);
lblMod0.setText("SEI SICURO DI VOLER DEFINITIVAMENTE ELIMINARE QUESTO RECORD ?");
btnMod.hide();
btnDel.hide();
btnConfdel.reshape(160,450,150,25);
btnConfdel.show();
}// ELIMINA DEFINITIVAMENTE IL RECORD
void confdel() {
output.println("cancella#"+stcodice);
try {
tmp = input.readLine();
if (tmp.equals("OK")) {
lblMod0.setText("ELIMINAZIONE ESEGUITA.");
stcodice="";
stcognome="";
stnome="";
stindir="";
stcitt="";
sttelef="";
txtMod1.setText("");
txtMod2.setText("");
txtMod3.setText("");
txtMod4.setText("");
txtMod5.setText("");
txtMod6.setText("");
lstCons.delItem(numrec);
}
else {
lblMod0.setText("ATTENZIONE : CANCELLAZIONE NON ESEGUITA.");
}
}
catch (java.io.IOException e) {
System.err.println("readLine memorizza error");
lblMod0.setText("ATTENZIONE : ERRORE NELL'AGGIORNAMENTO.");
}
}// INSERISCE UN NUOVO RECORD
// ATTENZIONE : IL CODICE E' UN CAMPO AUTOINC PER CUI VIENE GENERATO
// AUTOMATICAMENTE DAL DATABASE SUL SERVER
void memoins() {
stcognome=prepdb(txtIns2.getText().trim(),14);
stnome=prepdb(txtIns3.getText().trim(),18);
stindir=prepdb(txtIns4.getText().trim(),25);
stcitt=prepdb(txtIns5.getText().trim(),20);
sttelef=prepdb(txtIns6.getText().trim(),14);
output.println("inserisci#"+stcognome+"#"+stnome+"#"+stindir+"#"+stcitt+"#"+sttelef);
try {
tmp = input.readLine();
if (tmp.equals("KO")) {
lblIns0.setText("ATTENZIONE : INSERIMENTO NON ESEGUITO.");
}
else {
txtIns1.setText(tmp);
txtIns2.setText(stcognome);
txtIns3.setText(stnome);
txtIns4.setText(stindir);
txtIns5.setText(stcitt);
txtIns6.setText(sttelef);
lblIns0.setText("INSERIMENTO ESEGUITO.");
}
}
catch (java.io.IOException e) {
System.err.println("readLine memorizza error");
lblIns0.setText("ATTENZIONE : ERRORE NELL'INSERIMENTO.");
}
}// APRE UN SOCKET.
// IL COMPUTER VERSO CUI SI APRE IL SOCKET E' LO STESSO DA CUI
// E' STATO SCARICATO L'APPLET.
// VIENE CHIAMATO AUTOMATICAMENTE ALL'INIZIO DEL PROGRAMMA.
void aprisocket() {
if (ssock==0) {
try {
socket = new Socket(host,port);
input = new DataInputStream(socket.getInputStream());
output = new PrintStream(socket.getOutputStream());
ssock=1;
try {
tmp = input.readLine();
if(tmp.equals("Welcome")) {
lbl00.setText("Il server e' attivo.");
btnMenucons.enable();
btnMenuins.enable();
}
}
catch (java.io.IOException e) {
System.err.println("readLine error");
}
}
catch (java.io.IOException e) {
System.err.println ("Connection Failed");
lbl00.setText("ATTENZIONE: Il server NON e' attivo.");
}
}
}// CHIUDE IL SOCKET.
// VIENE CHIAMATO AUTOMATICAMENTE ALL'USCITA DAL PROGRAMMA.
void chiudisocket() {
if (ssock==1) {
ssock=0;
try {
socket.close();
} catch (IOException ex2) {
System.err.println("Errore in chiusura socket");
}
}
}// mette a blank i textfield per inserimento nuovo record
void blanktext() {
txtIns1.setText("");
txtIns2.setText("");
txtIns3.setText("");
txtIns4.setText("");
txtIns5.setText("");
txtIns6.setText("");
}// tronca il campo oppure aggiunge dei blank per arrivare alla lunghezza desiderata
String aggsp1(String stxx, int stlung) {
int stattu=stxx.length();
String retstr;
if (stattu>stlung) {
retstr=stxx.substring(0,stlung);
}
else {
retstr=stxx+nspazi(stlung-stattu);
}
return retstr;
}// genera una stringa di n spazi bianchi
String nspazi(int spn) {
StringBuffer retstr= new StringBuffer(0);
int ii;
for(ii = 0; ii < spn; ii++) {
retstr.append(' ');
}
return retstr.toString();
}// Prepara il campo per la trasmissione l'inserimento nel database
// Il campo deve essere troncato alla sua lunghezza massima.
// Se e' vuoto deve diventare un blank per essere trasmesso.
String prepdb(String stxx, int stlung) {
int stattu=stxx.length();
String retstr;
if (stxx.equals("")) {
retstr=" ";
}
else {
if (stattu>stlung) {
retstr=stxx.substring(0,stlung);
}
else {
retstr=stxx;
}
}
return retstr;
}}
MokaByte Web 1998 - www.mokabyte.it MokaByte ricerca nuovi collaboratori. Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it |