Con este patrón de diseño se puede implementar vista-controlador.
Este patrón de diseño resuelve el problema de actualizar un objeto cuando otro cambie de estado, estos objetos pueden ser componentes dentro de un frame o incluso otros frames.
Existe un observado (extends Observable) y un observador (implements Observer), el observado notifica al observador cuando cambia de estado, y el observador hace lo que crea conveninte con update(Observable obs, Object o).
Hay formas mucho más sencillas de hacer esto, pero aquí hay un ejemplo, el concepto es sencillo.
package voyerismo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import javax.swing.JComboBox;
/**
*
* @author fal
*
* Esta clase hereda de Observable, servirá para el primer combobox.
* Es como un exhibicionista
*
*/
public class Observado extends Observable{
private JComboBox jcombobox = null;
public Observado(){
String numeros[] = {"-","UNO", "DOS", "TRES","CUATRO"};
jcombobox = new JComboBox(numeros);
jcombobox.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
switch(jcombobox.getSelectedIndex() ){
//En cada case se cambia el estado, y se notifica a los observadores
case 1:
setChanged();
notifyObservers(jcombobox.getSelectedItem() );
break;
case 2:
setChanged();
notifyObservers(jcombobox.getSelectedItem() );
break;
case 3:
setChanged();
notifyObservers(jcombobox.getSelectedItem() );
break;
case 4:
setChanged();
notifyObservers(jcombobox.getSelectedItem() );
break;
default:
setChanged();
notifyObservers("");
}
}
});
}
/**
* Para obtener el combobox
* @return combobox El combobox que será espiado
*/
public JComboBox getCombobox(){
return this.jcombobox;
}
}
package voyerismo;
import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
/**
*
* @author fal
*
* Esta clase es la que observa al observado, es como el que estará espiando
* al combobox de la clase <code>Observado</code>
*
*/
public class Observador implements Observer{
private JComboBox combo = null;
private DefaultComboBoxModel modeloLight = null;
private String[] unos = { "Uno", "1", "i", "a", "I" };
private String[] doses = { "Dos", "2", "ii", "b", "II" };
private String[] treses = { "Tres", "3", "iii", "c", "III" };
private String[] cuatros = { "Cuatro", "4", "iv", "d", "IV" };
public Observador(){
modeloLight = new DefaultComboBoxModel();
combo = new JComboBox(modeloLight);
combo.setEnabled(false);
}
/**
* Aqui se implementa el método de la interfaz <code>Observer</code>
* el observado le notifica a éste para que éste haga lo tenga que hacer.
*
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*
*/
public void update(Observable observado, Object selectedItem) {
if(observado != null && (observado instanceof Observado) ){
if(selectedItem != null){
String str = selectedItem.toString();
if(str.equals("UNO") ){
enfria(unos);
combo.setEnabled(true);
}else if(str.equals("DOS") ){
enfria(doses);
combo.setEnabled(true);
}else if(str.equals("TRES") ){
enfria(treses);
combo.setEnabled(true);
}else if(str.equals("CUATRO") ){
enfria(cuatros);
combo.setEnabled(true);
}else{
enfria(new String[] {});
combo.setEnabled(false);
}
}
}
public JComboBox getCombobox(){
return this.combo;
}
/**
* Cambia el modelo(le hace un update)
* @param strings
*/
private void enfria(String[] strings){
modeloLight.removeAllElements();
for (String string : strings) {
modeloLight.addElement(string);
}
}
}
package voyerismo;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String args[]) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
Observado observado = new Observado();
Observador observador = new Observador();
//Se agregan los observadores al observado
observado.addObserver(observador);
JComboBox combo1 = observado.getCombobox();
JComboBox combo2 = observador.getCombobox();
panel.add(new JLabel("Observado") );
panel.add(combo1);
panel.add(new JLabel("ObservadoR") );
panel.add(combo2);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(panel);
frame.setTitle("Observado y observador");
frame.setSize(400, 100);
frame.setVisible(true);
}
}
Véase también:
http://en.wikipedia.org/wiki/Observer_pattern
http://www.lcc.uma.es/~pacog/apuntes/poo/Tema4-2.pdf
http://www.patterndepot.com/put/8/observer.pdf
http://java.sun.com/j2se/1.5.0/docs/api/java/util/class-use/Observable.html