Il sito dedicato all'informatica ideato da Iasparra Francesco

Observer e Observable


Nell'ambito della programmazione ad oggetti in Java si sono verificate situazioni in cui non si potevano risolvere problemi di comunicazione tra gli oggetti in modo semplice e senza nascondere il più possibile i dettagli implementativi. Questa astrazione non era possibile con i soli mezzi di programmazione primitiva offerta da Java, finchè sono stati introdotti i Design Pattern. L'idea era di andare oltre il riuso degli oggetti : di riuscire a far riusare il disegno degli oggetti creato per risolvere problemi ricorrenti, in modo tale che ogni oggetto conoscesse il meno possibile dell'ambiente in cui si trova.
Nel nostro caso, supponimo di avere due Jframe a cui vogliamo notificare a uno di essi un evento che si e' verificato sull'altro Jframe. Definiamo allora, il prima Jframe l'osservatore mentre l'altro l'osservato. L'osservatore implementa l'nterfaccia Observer di cui bisogna definire il metodo update(). L'osservato deve invece estendere la classe Observable, ma cio' non e' possibile poiche' quest'ultimo già estende la classe JFrame. Una soluzione a questo problema e' quello di generare l'oggetto MyObervable che verrà utilizzato dal Jframe osservato.

Vediamo l'esempio:

import java.util.Observable;
import java.util.Observer;

public class FormMain extends javax.swing.JFrame implements Observer{ // Classe che osserva
    
    public void update(Observable o, Object arg) {    // Metedo della classe update che viene eseguita a seguito della chiamata setChange()
        if(arg.toString().equals("FormLoadXML"))      //   
            this.jMenuItemLoadXML.setEnabled(true);
        if(arg.toString().equals("FormDBConnect"))
            this.jMenuItemConnect.setEnabled(true);
    }      
    
}

public class FormLoadXML extends javax.swing.JFrame { // Classe osservata
    
    private MyObservable objectFormLoadXML=null;
        
    public FormLoadXML{
        objectFormLoadXML=new MyObservable(); // crea un nuovo oggetto osservato
        objectFormLoadXML.addObserver((FormMain) parent); // specifica chi osserva
    }
    
    // supponiamo che a seguito della pressione del tasto di chiusura vogliamo informare l'osservatore
    private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {
          this.objectFormLoadXML.setStatus(); // Richiama il metodo setStatus
          this.objectFormLoadXML.notifyObservers("FormLoadXML"); // Notifica all'osservatore chi ha chiamato il metodo
    }    
}

public class MyObservable extends Observable { // Classe di appoggio
    
    public MyObservable() {}
        
    public void setStatus(){ // definiamo un metodo che verra' chiamato dall'osservato
        setChanged(); // E' definita in Obsevable e informa  l'osservatore che l'osservato
                      // ha generato una richiesta
    }
}    

Supponimo di chiudere il Jframe osservato, esso chiama i metodi setChange() e notifyObserver(), cio' verrà notificato al Observer quindi al Jframe che osserva che esegue il mtodo update(). Possiamo schematizzare il codice proposto in questo modo:

Observer observable 1

Nell'esempio viene illustrato come utilizzare la classe Observable e l'interfaccia Observer, attraverso i quali si disattiva e si attiva un voce nel menu' dell'oggetto FormMain da un oggetto FormLoadXML (jInternalFrame) esterno da cui non si può accedere direttamente.

Observer observable 2

Avviata l'applicazione osserviamo come il nel menu XML del FormMain sia attiva la voce LoadXML. Selezioniamo ora la voce di menu LoadXML. Compare a video il FormLoadXML

Observer observable 3

Se scorriamo dinuovo il menu' osserviamo che la voce LoadXML e' disabilitata. A questo punto se si chiude il FormLoadXML, la voce di menu corrispondente verrà riabilitata. Nella menu DB vi e' un altra voce che si abilita e disabilità con lo stesso procedimento.



  • Java

  • Php

  • Mysql

  • Apache ant

  • Eclipse

  • Spring

  • Hibernate

  • Netbeans

  • Debian

  • Linux

  • Maven