単純なプログラムを書換えよう(Java編)−Observer
GUIといえば,定番はMVC(Model-View-Controller).ということで,Observerを使ってMVCです.
動く順序はこうです.
- Viewを表示する際,ControllerのwindowOpenedメソッドが動く
- View(Observer)をModel(Observable)に登録
- ボタンを押す
- Controller(ActionListener)のactionPerformedメソッドが動く
- 押したボタンがincだったらModelのincメソッドを,decだったらModelのdecメソッドを呼ぶ
- Modelのincメソッドまたはdecメソッドの中でsetValueメソッドを呼び属性valueの値が変わる
- setChanged()とnotifyObserver()を呼ぶとView(Observer)のupdateメソッドが動く
- Viewの値が変わる
//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; import java.util.Observer; 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(); //押したボタンがincだったら,Modelのincメソッドを呼ぶ } else{ model.dec(); //押したボタンがdecだったら,Modelのdecメソッドを呼ぶ } } public void windowOpened(WindowEvent windowEvent){ model.addObserver((Observer)windowEvent.getSource()); //ViewをModelのObserverとして追加 model.setValue(model.getValue()); //Modelの初期値をViewに送る } public void windowClosing(WindowEvent windowEvent){ model.deleteObserver((Observer)windowEvent.getSource()); //閉じるViewをModelのObserverから削除 ((Frame)windowEvent.getSource()).dispose(); if(model.countObservers()==0){ //Modelに登録していたView(Observer)がなくなったらプログラム終了 System.exit(0); } } } //end //Model.java import java.util.Observable; public class Model extends Observable{ private int value; 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; setChanged(); notifyObservers(); //変化をObserverに通知 } 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(); } } //end //View.java import java.awt.*; import java.util.Observer; import java.util.Observable; public class View extends Frame implements Observer{ private Label value=new Label(); public View(Controller aController){ Panel buttons=new Panel(); Button inc=new Button("inc"); Button dec=new Button("dec"); buttons.add(inc); buttons.add(dec); inc.addActionListener(aController); dec.addActionListener(aController); add(buttons,BorderLayout.SOUTH); add(value,BorderLayout.CENTER); addWindowListener(aController); pack(); show(); } public void update(Observable obs,Object obj){ //Model(Observable)のnotifyObserverを受けてView(Observer)のupdateメソッドが動く value.setText(Integer.toString(((Model)obs).getValue())); } } //end //Main.java public class Main{ public static void main(String[] args){ new View(new Controller(new Model())); } } //end