山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

JavaFX で電卓を作る その2

電卓アプリの進捗

その1では、電卓のボタンを実装しましたが、割り算の記号"/"がなかったので、修正を行いました。その2では、四則演算と数字列の表示を実装しました。
計算はdouble型で定義しているので、整数同士の計算でも小数点が表示されます。


f:id:yamakasa3:20180303022302p:plain
f:id:yamakasa3:20180303022618p:plain

初めてのアプリで電卓を選んだのは大変だったかなと思いましたが、もう少し改善してみます。
コードとしては、ボタンの設定をfor文を用いて短く書くことができると思います。また、数字列の表示を行っているsetLabelTest()の全体の書き方がまずいことは理解できます。可読性や拡張性が酷いことに(´;ω;`)
本格的な実装を行うには、ポーランド記法?とかを理解する必要があると思います。現状は二つの数字の演算で手がいっぱいです。

JavaFXのコード

package application;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class Calculator extends Application{

	//計算と結果の表示
	Label label = new Label();

	//数字のボタン
	Button btn0 = new Button("0");
	Button btn1 = new Button("1");
	Button btn2 = new Button("2");
	Button btn3 = new Button("3");
	Button btn4 = new Button("4");
	Button btn5 = new Button("5");
	Button btn6 = new Button("6");
	Button btn7 = new Button("7");
	Button btn8 = new Button("8");
	Button btn9 = new Button("9");

	//演算子
	Button btnPlus = new Button("+");
	Button btnMinus = new Button("-");
	Button btnMultiplied = new Button("×");
	Button btnDivided = new Button("/");
	Button btnEqual = new Button("=");
	Button btnPlMi = new Button("±");
	Button btnPoint =  new Button(".");

	// クリアボタン
	Button btnClear = new Button("C");

	//ラベルの数字列
	String s1;
	String s2;

	//演算子
	String ope;

	//ラベルの数字列の長さ
	int lens1;
	int lens2;

	//計算結果
	double result;

	@Override
	public void start(Stage stage) throws Exception{
		stage.setTitle("MyCalculator");
		stage.setWidth(320);
		stage.setHeight(400);

		//ラベルの設定
		label.setText("0");
		label.setFont(new Font(30));
		label.setAlignment(Pos.TOP_RIGHT);
		label.setPrefWidth(300);
		label.setPrefHeight(30);

		// ラベルの数字列
		s1="0";
		s2="";
		lens1 = 1;
		lens2 = 0;

		//演算子
		ope = "";

		//ボタンのサイズ
		double a = 80;
		double b = 60;
		btn0.setPrefWidth(a);
		btn1.setPrefWidth(a);
		btn2.setPrefWidth(a);
		btn3.setPrefWidth(a);
		btn4.setPrefWidth(a);
		btn5.setPrefWidth(a);
		btn6.setPrefWidth(a);
		btn7.setPrefWidth(a);
		btn8.setPrefWidth(a);
		btn9.setPrefWidth(a);
		btnPlus.setPrefWidth(a);
		btnMinus.setPrefWidth(a);
		btnMultiplied.setPrefWidth(a);
		btnDivided.setPrefWidth(a);
		btnEqual.setPrefWidth(a);
		btnPlMi.setPrefWidth(a);
		btnPoint.setPrefWidth(a);

		btn0.setPrefHeight(b);
		btn1.setPrefHeight(b);
		btn2.setPrefHeight(b);
		btn3.setPrefHeight(b);
		btn4.setPrefHeight(b);
		btn5.setPrefHeight(b);
		btn6.setPrefHeight(b);
		btn7.setPrefHeight(b);
		btn8.setPrefHeight(b);
		btn9.setPrefHeight(b);
		btnPlus.setPrefHeight(b);
		btnMinus.setPrefHeight(b);
		btnMultiplied.setPrefHeight(b);
		btnDivided.setPrefHeight(b);
		btnEqual.setPrefHeight(b);
		btnPlMi.setPrefHeight(b);
		btnPoint.setPrefHeight(b);

		//ボタンの文字のサイズ
		int c = 20;
		btn0.setFont(new Font(c));
		btn1.setFont(new Font(c));
		btn2.setFont(new Font(c));
		btn3.setFont(new Font(c));
		btn4.setFont(new Font(c));
		btn5.setFont(new Font(c));
		btn6.setFont(new Font(c));
		btn7.setFont(new Font(c));
		btn8.setFont(new Font(c));
		btn9.setFont(new Font(c));
		btnPlus.setFont(new Font(c));
		btnMinus.setFont(new Font(c));
		btnMultiplied.setFont(new Font(c));
		btnDivided.setFont(new Font(c));
		btnEqual.setFont(new Font(c));
		btnPlMi.setFont(new Font(c));
		btnPoint.setFont(new Font(c));

		//クリアボタン
		btnClear.setPrefWidth(240);
		btnClear.setPrefHeight(b);
		btnClear.setFont(new Font(c));

		//ボタンの配置 行列で位置を表現
		GridPane grid = new GridPane();
		GridPane.setConstraints(btn7, 0, 0);
		GridPane.setConstraints(btn8, 1, 0);
		GridPane.setConstraints(btn9, 2, 0);
		GridPane.setConstraints(btn4, 0, 1);
		GridPane.setConstraints(btn5, 1, 1);
		GridPane.setConstraints(btn6, 2, 1);
		GridPane.setConstraints(btn1, 0, 2);
		GridPane.setConstraints(btn2, 1, 2);
		GridPane.setConstraints(btn3, 2, 2);
		GridPane.setConstraints(btn0, 1, 3);
		GridPane.setConstraints(btnPlus, 3, 0);
		GridPane.setConstraints(btnMinus, 3, 1);
		GridPane.setConstraints(btnMultiplied, 3, 2);
		GridPane.setConstraints(btnDivided, 3, 3);
		GridPane.setConstraints(btnPlMi, 0, 3);
		GridPane.setConstraints(btnPoint, 2, 3);

		// 数字ボタンと演算子ボタンを格納
		grid.getChildren().addAll(btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9,
				btnPlus, btnMinus, btnMultiplied, btnDivided, btnPlMi, btnPoint);

		// クリアボタンとイコールボタンを水平に配置
		HBox hbox = new HBox();
		hbox.getChildren().addAll(btnClear, btnEqual);

		//ボタンとラベルを垂直に配置する
		VBox root = new VBox();
		root.getChildren().addAll(label, grid,hbox);

		// 数字ボタンの機能
		btn0.setOnAction(event -> setLabelTest());
		btn1.setOnAction(event -> setLabelTest());
		btn2.setOnAction(event -> setLabelTest());
		btn3.setOnAction(event -> setLabelTest());
		btn4.setOnAction(event -> setLabelTest());
		btn5.setOnAction(event -> setLabelTest());
		btn6.setOnAction(event -> setLabelTest());
		btn7.setOnAction(event -> setLabelTest());
		btn8.setOnAction(event -> setLabelTest());
		btn9.setOnAction(event -> setLabelTest());
		btnClear.setOnAction(event -> setLabelTest());

		// 演算子ボタンの機能
		btnPlus.setOnAction(event -> setLabelTest());
		btnMinus.setOnAction(event -> setLabelTest());
		btnMultiplied.setOnAction(event -> setLabelTest());
		btnDivided.setOnAction(event -> setLabelTest());

		// イコールボタンの機能
		btnEqual.setOnAction(event -> calc());

		stage.setScene(new Scene(root));
		stage.show();
	}

	void setLabelTest() {
		//表示されている数字列が0だけの場合、1-9で上書きする。
		if(s1.equals("0")) {
			if(btn1.isArmed()) {s1 = "1";}
			if(btn2.isArmed()) {s1 = "2";}
			if(btn3.isArmed()) {s1 = "3";}
			if(btn4.isArmed()) {s1 = "4";}
			if(btn5.isArmed()) {s1 = "5";}
			if(btn6.isArmed()) {s1 = "6";}
			if(btn7.isArmed()) {s1 = "7";}
			if(btn8.isArmed()) {s1 = "8";}
			if(btn9.isArmed()) {s1 = "9";}
			if(btnPlus.isArmed()) {s1 += "+";}
			if(btnMinus.isArmed()) {s1 += "-";}
			if(btnMultiplied.isArmed()) {s1 += "×";}
			if(btnDivided.isArmed()) {s1 += "/";}
		}else if(s1.matches("^[0-9]+$") && ope == ""){
			if(btn0.isArmed()) {s1 += "0";}
			if(btn1.isArmed()) {s1 += "1";}
			if(btn2.isArmed()) {s1 += "2";}
			if(btn3.isArmed()) {s1 += "3";}
			if(btn4.isArmed()) {s1 += "4";}
			if(btn5.isArmed()) {s1 += "5";}
			if(btn6.isArmed()) {s1 += "6";}
			if(btn7.isArmed()) {s1 += "7";}
			if(btn8.isArmed()) {s1 += "8";}
			if(btn9.isArmed()) {s1 += "9";}
			if(btnPlus.isArmed()) {ope = "+";}
			if(btnMinus.isArmed()) {ope = "-";}
			if(btnMultiplied.isArmed()) {ope = "×";}
			if(btnDivided.isArmed()) {ope = "/";}
		}
		if(!ope.equals("")) {
			if(s2.equals("0")) {
				if(btn1.isArmed()) {s2 = "1";}
				if(btn2.isArmed()) {s2 = "2";}
				if(btn3.isArmed()) {s2 = "3";}
				if(btn4.isArmed()) {s2 = "4";}
				if(btn5.isArmed()) {s2 = "5";}
				if(btn6.isArmed()) {s2 = "6";}
				if(btn7.isArmed()) {s2 = "7";}
				if(btn8.isArmed()) {s2 = "8";}
				if(btn9.isArmed()) {s2 = "9";}
			}else {
				if(btn0.isArmed()) {s2 += "0";}
				if(btn1.isArmed()) {s2 += "1";}
				if(btn2.isArmed()) {s2 += "2";}
				if(btn3.isArmed()) {s2 += "3";}
				if(btn4.isArmed()) {s2 += "4";}
				if(btn5.isArmed()) {s2 += "5";}
				if(btn6.isArmed()) {s2 += "6";}
				if(btn7.isArmed()) {s2 += "7";}
				if(btn8.isArmed()) {s2 += "8";}
				if(btn9.isArmed()) {s2 += "9";}
			}
		}
		if(btnClear.isArmed()) {
			s1 = "0";
			s2 = "";
			ope = "";
		}
		label.setText(s1+ope+s2);
	}

	//計算機能 s1とs2の演算を行う
	void calc() {
		if(ope.equals("+") && (s2.matches("^[0-9]+$"))) {
			result = Double.valueOf(s1) +  Double.valueOf(s2);
			label.setText(String.valueOf(result));
		}else if(ope.equals("-") && (s2.matches("^[0-9]+$"))){
			result = Double.valueOf(s1) -  Double.valueOf(s2);
			label.setText(String.valueOf(result));
		}else if(ope.equals("×") && (s2.matches("^[0-9]+$"))){
			result = Double.valueOf(s1) *  Double.valueOf(s2);
			label.setText(String.valueOf(result));
		}else if(ope.equals("/") && (s2.matches("^[0-9]+$"))){
			result = Double.valueOf(s1) /  Double.valueOf(s2);
			label.setText(String.valueOf(result));
		}
	}

	public static void main(String[] args) {
		launch(args);
	}
}