単純なプログラムを書換えよう(Java編)−java.util.Propertiesの使用
引数のあるコンストラクタをCommandに定義のCommandDispatcherクラスで行っている,画面から受け取った文字列と実行するコマンドのひも付けを,プロパティファイルを使ってやってみよう.具体的には,こんなファイル(command.properties)を作るわけだ.
inc=IncCommand dec=DecCommand
このファイルを読んで,ボタンを押した際に実行するコマンドを決める.変更箇所はCommandDispatcher.javaである.
//CommandDispatcher.java import java.lang.reflect.*; import java.util.Map; import java.util.Properties; //プロパティファイルを使うのでインポート import java.io.*; public class CommandDispatcher{ private static Map commands; private static CommandDispatcher commandDispatcher=new CommandDispatcher(); private static Model model; static{ //HashMapに設定していた文字列とCommandクラスとの対応を,プロパティファイルからの読込みに変更. Properties prop=new Properties(); try{ prop.load(new FileInputStream("command.properties")); } catch(FileNotFoundException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } commands=(Map)prop; //PropertiesからMapへ変換 } private CommandDispatcher(){ } public static CommandDispatcher getInstance(Model model){ commandDispatcher.model=model; return commandDispatcher; } public Command getCommand(String command){ Command executeCommand=null; try{ Class aClass=Class.forName(commands.get(command).toString()); //生成するクラスを取得.インスタンスはまだできていない Class[] classArgs={this.model.getClass()}; //コンストラクタに渡す引数で配列作成.引数はインスタンスではなくクラス Constructor aCons=aClass.getConstructor(classArgs); //配列に設定した引数を持つコンストラクタを取得 Object[] objArgs={this.model}; //コンストラクタに渡す引数で配列作成.次行でコンストラクタを動かすのでインスタンス executeCommand=(Command)aCons.newInstance(objArgs); //引数を指定してコンストラクタを起動.インスタンスを取得 } catch(ClassNotFoundException e){ e.printStackTrace(); } catch(NoSuchMethodException e){ e.printStackTrace(); } catch(InstantiationException e){ e.printStackTrace(); } catch(IllegalAccessException e){ e.printStackTrace(); } catch(InvocationTargetException e){ e.printStackTrace(); } return executeCommand; } } //end
ちなみに,command.propertiesを書換えて,
inc=DecCommand dec=IncCommand
とすると,incボタンで減算,decボタンで加算できる.そんなことをしてどうするのか,ってのは置いといて.
CommandDispatcher.java以外のソースには変更はない.参考に以下に載せとこう.
//Command.java public interface Command{ void execute(); } //end //IncCommand.java public class IncCommand implements Command{ private Model model; public IncCommand(Model model){ this.model=model; } public void execute(){ model.inc(); } } //end //DecCommand.java public class DecCommand implements Command{ private Model model; public DecCommand(Model model){ this.model=model; } public void execute(){ model.dec(); } } //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; import java.util.Observer; public class Controller extends WindowAdapter implements ActionListener{ private Model model; private CommandDispatcher commandDispatcher; public Controller(Model model){ commandDispatcher=CommandDispatcher.getInstance(model); this.model=model; } public void actionPerformed(ActionEvent actionEvent){ commandDispatcher.getCommand(actionEvent.getActionCommand()).execute(); } public void windowOpened(WindowEvent windowEvent){ model.addObserver((Observer)windowEvent.getSource()); model.setValue(model.getValue()); } public void windowClosing(WindowEvent windowEvent){ model.deleteObserver((Observer)windowEvent.getSource()); ((Frame)windowEvent.getSource()).dispose(); if(model.countObservers()==0){ 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(); } 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 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 update(Observable obs,Object obj){ 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