単純なプログラムを書換えよう(Java編)−EventListener
ObserverではなくEventListenerを使ったMVCです.Observerの場合,Model(Observable)クラスに持たせていたaddObserver/deleteObserverメソッドは,Modelクラスがjava.util.Observableを継承することで取得していました.EventListenerを使う場合,ModelクラスのaddValueListener/removeValueListenerメソッドとして独自に実装しています.JavaWorld 1999年6月号 p.116~122参照です.
//ValueEvent.java import java.util.EventObject; public class ValueEvent extends EventObject{ public ValueEvent(Model model){ super(model); } public int getValue(){ return ((Model)source).getValue(); } } //end //ValueEvent.java import java.util.EventListener; public interface ValueListener extends EventListener{ public void valueChanged(ValueEvent valueEvent); } //end //Controller.java import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.awt.Frame; public class Controller extends WindowAdapter implements ActionListener{ private Model model; public Controller(Model model){ this.model=model; } public void actionPerformed(ActionEvent actionEvent){ if(actionEvent.getActionCommand()=="inc"){ model.inc(); } else{ model.dec(); } } public void windowOpened(WindowEvent windowEvent){ model.addValueListener((ValueListener)windowEvent.getSource()); model.setValue(model.getValue()); } public void windowClosing(WindowEvent windowEvent){ model.removeValueListener((ValueListener)windowEvent.getSource()); ((Frame)windowEvent.getSource()).dispose(); if(model.countValueListeners()==0){ System.exit(0); } } } //end //Model.java import java.util.Set; import java.util.HashSet; import java.util.Iterator; public class Model{ private int value; private Set listeners=new HashSet(); public Model(){ this(0); } public Model(int value){ setValue(value); } public final int getValue(){ return value; } public final void setValue(int value){ this.value=value; fireValueChanged(); } public int inc(){ return inc(1); } public int inc(int value){ setValue(getValue()+value); return getValue(); } public int dec(){ return dec(1); } public int dec(int value){ setValue(getValue()-value); return getValue(); } public int countValueListeners(){ return listeners.size(); } public void addValueListener(ValueListener valueListener){ if(!listeners.contains(valueListener)){ listeners.add(valueListener); } } public void removeValueListener(ValueListener valueListener){ listeners.remove(valueListener); } public void fireValueChanged(){ ValueEvent event=new ValueEvent(this); for(Iterator i=listeners.iterator();i.hasNext();){ ((ValueListener)i.next()).valueChanged(event); //変化をValueListenerに通知 } } } //end //View.java import java.awt.*; public class View extends Frame implements ValueListener{ private Label value=new Label(); public View(Controller controller){ Panel buttons=new Panel(); Button inc=new Button("inc"); Button dec=new Button("dec"); buttons.add(inc); buttons.add(dec); inc.addActionListener(controller); dec.addActionListener(controller); add(buttons,BorderLayout.SOUTH); add(value,BorderLayout.CENTER); addWindowListener(controller); pack(); show(); } public void valueChanged(ValueEvent valueEvent){ value.setText(Integer.toString(valueEvent.getValue())); //ModelのfireValueChangedを受けてViewのvalueChangedメソッドが動く } } //end //Main.java public class Main{ public static void main(String[] args){ new View(new Controller(new Model())); } } //end