新しい状態(State)を追加する
まだ電卓にはエラー処理が実装されていません。例えば1÷0=と入力すると「Infinity」と表示されてしまいます。桁あふれのエラー処理もないため、桁あふれしたことが分かりません。
また、エラーが発生した場合にはAC(All Clear)ボタン以外受け付けないように制御したいとおもいます。そのためには新しい状態(State)を追加します。
新しい状態(State)を追加するのは簡単です。Stateインターフェースを実装したクラスを追加します。そしてAC(All Clear)ボタンが押されたときにエラーをクリアするように実装します。
public class ErrorState implements State {
private static ErrorState singleton = new ErrorState();
private ErrorState() { // コンストラクタはprivate
}
public static State getInstance() { // 唯一のインスタンスを得る
return singleton;
}
@Override
public void onInputNumber(Context context, Number num) {
}
@Override
public void onInputOperation(Context context, Operation op) {
}
@Override
public void onInputEquale(Context context) {
}
@Override
public void onInputClear(Context context) {
}
@Override
public void onInputAllClear(Context context) {
context.clearA();
context.clearB();
context.clearDisplay();
context.clearError();
context.changeState(NumberAState.getInstance());
}
}
あとは、演算時のエラーを検出したらExceptionを継承したCalcExceptionをスローするように変更します。
public double doOperation() throws CalcException{
double result = op.eval(A, B);
// Doubleの場合、ゼロ割でエラーが発生しないので注意が必要。
if (Double.isInfinite(result) || Double.isNaN(result)) {
throw new CalcException();
}
showDisplay(result);
// 演算結果がディスプレイからはみ出ないかチェック
if (disp.isOverflow(result)) {
throw new CalcException();
}
return result;
}
上記変更により、CalcクラスのdoOperation()メソッドを呼び出している箇所がエラーになるので、try-catch文でErrorStateへ遷移するように変更します。
public void onInputOperation(Context context, Operation op) {
try {
context.saveDisplayNumberToB();
context.doOperation();
context.setOp(op);
context.saveDisplayNumberToA();
context.changeState(OperationState.getInstance());
} catch (CalcException e) {
context.setError();
context.changeState(ErrorState.getInstance());
}
}
そのほかのdoOperation()メソッドを呼び出している箇所も同様に修正します。
修正は以上です。 実際に動かしてみましょう。例えばゼロ割である1÷0=や、桁溢れする9999999×9999999=などを計算してみてください。ErrorStateに遷移するのでACボタン以外反応しなくなることが分かると思います。
どうでしょうか。簡単にエラー状態が追加できることが理解できたかと思います。
トースト通知の追加
電卓アプリ内部ではErrorStateによりエラー状態であることが分かりますが、Androidアプリ上ではエラーになったことが分かりません。そこでAndroidの通知機能「トースト」を使用してエラーを通知するように機能を追加します。
トーストとは前面に表示される通知のことです。画面の下方に表示され、自動でフェードイン、フェードアウトされます。トースト表示中も現在の画面が見えたままなので、アプリケーションの操作も可能です。
トーストの表示自体は大変簡単です。Calcクラスに追加しましょう。トースト表示用にContextを保持できるようにメンバ変数parentを追加します。setDispメソッドでContextを受け取りparentに設定することにします。
// Toast表示用にcontextを持つ。
protected android.content.Context parent;
public void setDisp(TextView txt,android.content.Context parent){
this.disp = new StringDisplay(txt);
this.parent = parent;
}
MainActivityクラスのsetDisp呼び出しも修正しておきます。
calc.setDisp(txtDisp,this);
トーストを表示するにはToast クラスを使用します。
public void setError() {
if (parent != null){
Toast.makeText(parent, "ERROR", Toast.LENGTH_LONG).show();
}
disp.setError();
}
実行してみましょう。演算エラーになる操作を行うとERRORの文字が表示されます。
