Tips&Tricks I trucchi del mestiere

 

Gestione avanzata eccezioni!


La gestione delle eccezioni Φ sempre un problema, con questo mini framework Φ possibile proteggere il codice ôpericolosoö in unÆapposita struttura che faciliterα la gestione delle eccezioni o che permetterα di utilizzare metodi con eccezioni checked senza il blocco try/catch e senza perdere lÆeventuale eccezione scatenata!
Tip fornito dal sig. S.Fago

/**
* Classe dÆutilitα per uso dei TryMethodsà
*/
public class ExceptionUtil {
  private ExceptionUtil() {}

  public static Object execute(TryMethod method,java.util.Collection args){
   try {
          return method.execute(args);
       }catch (Exception ex) { return ex;  }
    }
}//end

/**
 * Interfaccia che stabilisce il contratto di un TryMethod da implementare per le 
 * RuntimeExceptionà 
 */
public interface TryMethod{
   public Object execute(java.util.Collection args);
}

/**
* Implementazione di TryMethod per le checked exceptionà
*/
public class ReflectiveMethod implements TryMethod{
    private Object target;
    private String methodName;
    private Class[] paramTypes;

    public void init(Object target, String methodName, Class [] paramTypes){
     this.target = target;
     this.methodName = methodName;
     this.paramTypes = paramTypes;
    }

    public Object execute(java.util.Collection args){
     try {
          Class clazz = target instanceof Class?(Class)target:target.getClass();
          return (clazz.getDeclaredMethod(methodName,paramTypes)).invoke(  (target instanceof Class?null:target),args.toArray());
     }catch (java.lang.reflect.InvocationTargetException iex){return iex.getTargetException();}catch (Exception ex) {return ex;}
    }
  }//end



Un semplice blocco note


La class java allegata implementa un semplice blocco note, tipo quello di Windows, capace di gestire, grazie ai flussi di I/O messi a disposizione da java, i file di testo (carica/salvataggio).Nello sviluppo dell'applicazione si Φ deciso di non utilizzare massicciamente le opzioni grafiche delle JFrame, questo per mettere in rilevanza le potenzialitα dei flussi di java.
Tip fornito dal sig. A.Avolio

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class BloccoNotes implements WindowListener, ActionListener{

  //Istanze della classe
  private Frame finestra;
  private TextArea areaTesto;

  //Costruttore della classe

   public BloccoNotes(Frame f, TextArea t) {
     finestra = f;
     areaTesto = t;
   }

  //Gestione della grafica

  // Metodi non implementati dell'interfaccia WindowListener
  public void windowActivated(WindowEvent evt) {}
  public void windowDeactivated(WindowEvent evt) {}
  public void windowDeiconified(WindowEvent evt) {}
  public void windowIconified(WindowEvent evt) {}
  public void windowOpened(WindowEvent evt) {}

  // Metodi implementati dell'interfaccia WindowListener
  public void windowClosed(WindowEvent evt) {
    System.exit(0);
  }

  public void windowClosing(WindowEvent evt) {
    finestra.dispose();
  }

  // Metodo acoltatore ha il computo di ascoltare i comandi
  public void actionPerformed(ActionEvent evt) {
    String comando = evt.getActionCommand();
    //gestione dei vari eventi
    if (comando.equals("Esci")) {
      finestra.dispose();
    } else if (comando.equals("Apri")) {
      areaTesto.setText("");
      FileDialog d = new FileDialog(finestra, "Apri documento", FileDialog.LOAD);
      d.setVisible(true);
      if (d.getFile() != null) {
        try {
          String line;
          BufferedReader in = new BufferedReader(new FileReader(d.getDirectory() + File.separator + d.getFile()));
          while ((line = in.readLine()) != null)
            areaTesto.append(line + "\n");
        } catch (Exception e) {
          System.out.println("Errore: " + e);
        }
      }
    } else if (comando.equals("Salva con nome...")) {
      FileDialog d = new FileDialog(finestra, "Salva documento con nome", FileDialog.SAVE);
      d.setVisible(true);
      PrintWriter fout;
      String Stringa=areaTesto.getText();
      try{
        fout=new PrintWriter(new FileWriter(d.getDirectory()+File.separator+d.getFile()));
        StringTokenizer st=new StringTokenizer(Stringa,"\n"); //E' importante per gestire la pressione dell'invio
        while (st.hasMoreTokens())
          fout.println(st.nextToken());
        fout.close();
      }catch(Exception e){}
  }
}

  /** Metodo Main */
  public static void main(String[] args) {
    Frame f = new Frame("My blocco note ");
    TextArea t = new TextArea();
    BloccoNotes n = new BloccoNotes(f, t);
    MenuBar mb = new MenuBar();

    // Preparazione men∙ file il menu File
    Menu menu = new Menu("File");
    mb.add(menu);
    menu.add("Apri");
    menu.add("Salva con nome...");
    menu.addSeparator();
    menu.add("Esci");

    menu.addActionListener(n);

    // Prepara la finestra
    f.addWindowListener(n);
    f.setMenuBar(mb);
    f.add(t);
    f.setSize(400, 500);
    f.setVisible(true);
  }
} // BloccoNotes


Connessioni JDBC condivise


La libreria proposta, tramite poche istruzioni, consente di accedere ad un insieme di connessioni jdbc da poter utilizzare in maniera condivisa; questo perchΦ il pool dichiara, istanzia e gestisce le connessioni per noi, permettendo il riutilizzo delle stesse tramite un booleano indicante lo stato della connessione; al termine dell'elaborazione la connessione non viene chiusa ma semplicemente rilasciata; se alla richiesta di una connessione quelle attualmente in pool sono tutte occupate, e se il limite massimo di connessioni stabilito non Φ stato superato, ne verrα creataautomaticamente una nuova. Complementare a questo, un thread che si occupa di controllare periodicamente il pool per verificare se esiste qualche connessione non rilasciata oltre un tempo massimo stabilito. Tutto questo e molto di pi∙ Φ ampiamente spiegato nel file readme allegato.
Tip fornito dal sig. R. Favaroni

Descrizione delle classi contenute nellÆarchivio Java connectionpool.jar

ConnectionItem: Bean che mappa la singola connessione.

ConnectionManager: Thread dedicato al controllo periodico del pool delle connessioni alla ricerca di connessioni appese.

ConnectionParameters: Bean che mappa i parametri acquisiti da file properties.

ConnectionPool: Gestore del pool di connessioni.

MaxNumberConnectionException: Eccezione sollevata per la richiesta di connessioni superiori al limite stabilito.

Tester: Utility per effettuare stress test e benchmark fra connessioni in pool e connessioni singole.

PropertiesFileHandler: Wrapper per la lettura di file properties.



Ordinare un array bidimensionale



Il tip proposto consente di ordinare alfabeticamente un array bidimensionale, in questo caso formato da 5 righe e 4 colonne (nome = newString[5][4]) ma pu≥ essere molto pi∙ grande. Il confronto Φ fatto dal primo elemento di ogni riga come se si trattasse di un array monodimensionale, mentre lo scambio avviene di tutta la riga.L'ordinamento pu≥ essere fatto prendendo in considerazione altri elementi delle colonne.
Nell'esempio le righe risultano ordinate considerando per il confronto la prima colonna, se si vogliono ordinare le righe tenendo conto della seconda colonna sostituire nome[k][0] con nome[k][1] all'interno dell'unica istruzione condizionale if.
Tip fornito dal sig. G.Urso


import java.io.PrintStream;
public class Ordinamento
{
public Ordinamento()
{
nome = new String[5][4];
nome[0][0] = "Rossi Paolo ";
nome[0][1] = "Garibaldi n\260 34 ";
nome[0][2] = "Roma ";
nome[0][3] = "00100 ";
nome[1][0] = "Rossi Mario ";
nome[1][1] = "Mazzini n\260 14 ";
nome[1][2] = "Milano ";
nome[1][3] = "20100 ";
nome[2][0] = "Rossi Francesca ";
nome[2][1] = "Napoleone n\260 121 ";
nome[2][2] = "Milano ";
nome[2][3] = "20100 ";
nome[3][0] = "Rossi Giovanni ";
nome[3][1] = "Lincolm n\260 12 ";
nome[3][2] = "Torino ";
nome[3][3] = "10100 ";
nome[4][0] = "Rossi Alberto ";
nome[4][1] = "Cattaneo n\260 176 ";
nome[4][2] = "Bologna ";
nome[4][3] = "40100 ";
System.out.println(" SCRITTURA DISORDINATA ALFABETICAMENTE");
System.out.println(" ");
System.out.println("Cognome e nome Via Citt\340 C.A.P. ");
System.out.println(" ");
for(x = 0; x < 5; x++)
{
System.out.println(" ");
for(j = 0; j < 4; j++)
System.out.print(nome[x][j]);
}

for(int i = nome.length - 1; i >= 0; i--)
{
for(int k = 1; k <= i; k++)
if(nome[k][0].compareTo(nome[k - 1][0]) < 0)
{

nomeb = new String[5];
for(int l = 0; l < 4; l++)
{
nomeb[l] = nome[k - 1][l];
nome[k - 1][l] = nome[k][l];
nome[k][l] = nomeb[l];
nomeb[l] = "";
}
}
}

System.out.println(" ");
System.out.println(" ");
System.out.println(" ");
System.out.println(" SCRITTURA ORDINATA ALFABETICAMENTE");
for(x = 0; x < 5; x++)
{
System.out.println(" ");
for(j = 0; j < 4; j++)
System.out.print(nome[x][j]);
}
}

public static void main(String args[])
{ Ordinamento ordinamento = new Ordinamento(); }

int x;
int j;
String nome[][];
String nomeb[];
}

Passare valori tra pagine web


Il codice JavaScript permette di passare i valori di variabili tra pagine senza l'uso di php, cgi o cookies semplicemente sfruttando l'url della pagina. La pagina di "partenza" quando chiama la pagina "ricevente" il valore deve rispettare la seguente sintassi:
"indirizzo?variabile1=valore1&variabile2=valore2&variabile3=valore3", ovvero quella che, generalmente, viene utilizzata dai form utilizzando il metodo "GET".
Per poter ottenere il valore di una variabile Φ sufficiente chiamare la funzione leggivarabile passandole come parametro semplicemente il nome della variabile stessa.
In allegato un file ".htm" dÆesempio che mostra il funzionamento dello script anche in coppia con i form.
Tip fornito dal sig. I. Scarabello


function leggivariabile(variabile) {
               // variabile contiene il nome della variabile
         var indirizzo = window.location.toString() + "&";
               // indirizzo contiene l'indirizzo della pagina nella forma
               // "indirizzo?variabile1=valore1&variabile2=valore2&variabile3=valore3&"
         var posizionenome=indirizzo.indexOf(variabile + "=");
               // trova la posizione in cui e' memorizzata la variabile
         if (posizionenome==-1) return "";
               // se restituisce -1 la variabile non c'e'! :(
         var sottostringa=indirizzo.substring(posizionenome);
               // taglia tutto quello che c'e' prima della variabile
         var inizio=sottostringa.indexOf("=");
               // trova l'uguale dopo il quale si trova il valore
         var fine=sottostringa.indexOf("&");
               // trova la & che indica dove finisce il valore
         var variabile=sottostringa.substring(inizio + 1, fine);
               // assegna a variabile il valore contenuto tra = e &!

        return variabile;
}



Passare valori tra pagine web


Il codice JavaScript permette di passare i valori di variabili tra pagine senza l'uso di php, cgi o cookies semplicemente sfruttando l'url della pagina. La pagina di "partenza" quando chiama la pagina "ricevente" il valore deve rispettare la seguente sintassi:
"indirizzo?variabile1=valore1&variabile2=valore2&variabile3=valore3", ovvero quella che, generalmente, viene utilizzata dai form utilizzando il metodo "GET".
Per poter ottenere il valore di una variabile Φ sufficiente chiamare la funzione leggivarabile passandole come parametro semplicemente il nome della variabile stessa.
In allegato un file ".htm" dÆesempio che mostra il funzionamento dello script anche in coppia con i form.
Tip fornito dal sig. I. Scarabello


import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.rtf.*;

/**
 * Titolo: RTFView
 * Descrizione: Visualizza RTF in pagine Web
 * @author Gianluca Esposito (giaesp@tiscali.it)
 * @version 0.11.17.03
 */

public class RTFView
    extends JApplet {

  private boolean isStandalone = false;
  JScrollPane rtfScroller = new JScrollPane();
  JTextPane rtfPane = new JTextPane();

  String RTFText;
  int bground;

  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
        (getParameter(key) != null ? getParameter(key) : def);
  }

  public RTFView() {
  }

  public void init() {
    try {
      RTFText = this.getParameter("RTF",
                                  "Nessuna informazione da visualizzare.");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      bground = Integer.parseInt(this.getParameter("bground", "FFFFFF"), 16);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      jbInit();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    // this.setSize(new Dimension(width,height));
    rtfPane.setEditorKit(new RTFEditorKit());
    rtfPane.setEditable(false);
    rtfPane.setCaretPosition(0);
    rtfPane.setText(RTFText); // Inserimento del testo RTF
    this.getContentPane().add(rtfScroller, BorderLayout.CENTER);
    rtfScroller.getViewport().add(rtfPane, null);
    rtfPane.setBackground(new Color(bground));
    rtfScroller.setBackground(new Color(bground));
    this.setVisible(true);
  }

  public void start() {
  }

  public void stop() {
  }

  public void destroy() {
  }

  public String getAppletInfo() {
    return "RTFView 0.11.17.03 (Gianluca Esposito - giaesp@tiscali.it)";
  }

  public String[][] getParameterInfo() {
    String[][] pinfo = {
        { "RTF", "String", "Corpo dell'RTF"},
        { "bground", "hex int", "Colore di sfondo - Inserire sequenza esadecimale (come nell'HTML, ma senza \"#\")"},
    };
    return pinfo;
  }

  static {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (Exception e) {
    }
  }
}