簡単なGUI作品制作例 電卓 ステップ5(例外処理)

前のページ)の 作成で、+−*/=の演算ボタンのイベント処理を追加ました。 演算キーを押した時に、前に押した演算キーによる演算結果を上のラベルに表示する方法でした。

しかしここでは、操作を間違と次のような実行エラーが生じます。
Exception in thread "AWT-EventQueue-0"
java.lang.NumberFormatException: For input String: ??
at sun.misc.FloatingDecimal.readJavaFormatString(省略)
・・・省略・・・

演算キーで下部のテキストフィールドと上部ラベルを演算しているのですが、 操作を間違えると、空白などのテキストフィールドで演算され、 数字以外の入力と判断されるためです。 (また、ドットが複数入力した場合も同様の実行エラーになります)
 そこで、この文字列から数値変換において起きるNumberFormatException例外をキャッチして 次のダイアログを表示させます。そして、この表示の時のキー操作ーは無視することとします。
これは次のコードで表示されます。
JOptionPane.showMessageDialog(this, "数字入力に問題があります。\n変更ください。");
thisで指定するのは、フレームやパネルオブジェクトです。 (JOptionPaneはjavax.swingのパッケージにあります)

なお、演算で四則演算( + - / * )のキーのいずれかを連続して 入力する操作ミスに対して、後で入力した方のキーを有効にします。
そして、= のキーを連続して入力した場合はラベルの表示もゼロにします。

以下は、この動作ができるようにNomalCalcPanelを変更したプログラム例です。
『演算キー直後の時だけtrue』となる変数opFlagを用意して、 それがtrueの時で、下のテキストフィールドが空でない時に 演算キーをクリックしたら、演算キーが変更されたことを示すダイアログも表示させています。

public class NomalCalcPanel extends SimpleCalcPanel implements ActionListener{
	boolean  opFlag = false; // 演算キー直後の時だけtrueにする。
	
	・・・省略・・
	
	public void actionPerformed2(ActionEvent e){
		if (e.getSource() instanceof JButton == false) return;
		super.actionPerformed(e);
		JButton btn = (JButton)e.getSource();
		String str = btn.getText();
		if (str.equals("+") || str.equals("-") ||
			str.equals("*") || str.equals("/") ||
			str.equals("=")) {
			if (backOp == '=') {
				if(str.equals("=")){
					this.lbl1.setText("0");//2回連続して=の場合はクリア
					this.txt1.setText("");
					this.backOp = '=';
					return;
				}

				if (this.txt1.getText().equals(""))	{
					this.backOp = str.charAt(0);
					return;
				}
				try {
					double d2 = Double.parseDouble(this.txt1.getText());
					this.lbl1.setText(this.txt1.getText());
				}
				catch (NumberFormatException err1) {
					JOptionPane.showMessageDialog(this, "数字入力に問題があります。\n変更ください。");
					return;
				}
			} else {
				if (this.opFlag) {
					if (this.backOp == str.charAt(0)) return;
					JOptionPane.showMessageDialog(this, "以前の『"+backOp+"』キーーを無効にし、 \n『" + str + "』このキーを有効にします。");
					this.backOp = str.charAt(0);
					return;
				}
				double d1 = 0;
				double d2 = 0;
				try {
					d1 = Double.parseDouble(this.lbl1.getText());
					d2 = Double.parseDouble(this.txt1.getText());
				}
				catch(NumberFormatException err1) {
					JOptionPane.showMessageDialog(this, "数字入力に問題があります。\n変更ください。");
					return;
				}
				if (backOp == '+') {
					this.lbl1.setText("" + (d1 + d2));
				} else if (backOp == '-') {
					this.lbl1.setText("" + (d1 - d2));
				} else if (backOp == '*') {
					this.lbl1.setText("" + (d1 * d2));
				} else if (backOp == '/') {
					this.lbl1.setText("" + (d1 / d2));
				}
			}
			this.txt1.setText("");
			this.backOp = str.charAt(0);
			this.opFlag = true;
		}else{
			this.opFlag = false;
		}
	}
	
	・・・省略・・

}