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

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

JavaFX で電卓を作る その3

前回の電卓の機能を改善し、負の整数を扱えるようにしました。また、ボタンを作成する部分を配列を用いて表現しました。次は小数を扱う機能を実装したいと思います。

最近はアルゴリズムの問題を解くことをやっていないので、近いうちにやりたいと思います。

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 btn[] = new Button[10];

	//演算子
	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(420);
		stage.setHeight(400);

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

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

		//演算子
		ope = "";

		//ボタンのサイズ
		double a = 80;
		double b = 60;
		int c = 20;

		// 数字のボタン
		//String[] btnText = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
		btn[0] = new Button("0");
		btn[1] = new Button("1");
		btn[2] = new Button("2");
		btn[3] = new Button("3");
		btn[4] = new Button("4");
		btn[5] = new Button("5");
		btn[6] = new Button("6");
		btn[7] = new Button("7");
		btn[8] = new Button("8");
		btn[9] = new Button("9");
		for(int i = 0; i < 10; i++) {
			btn[i].setPrefHeight(b);
			btn[i].setPrefWidth(a);
			btn[i].setFont(new Font(20));
		}

		btnPlus.setPrefWidth(a);
		btnMinus.setPrefWidth(a);
		btnMultiplied.setPrefWidth(a);
		btnDivided.setPrefWidth(a);
		btnEqual.setPrefWidth(a);
		btnPlMi.setPrefWidth(a);
		btnPoint.setPrefWidth(a);

		btnPlus.setPrefHeight(b);
		btnMinus.setPrefHeight(b);
		btnMultiplied.setPrefHeight(b);
		btnDivided.setPrefHeight(b);
		btnEqual.setPrefHeight(b);
		btnPlMi.setPrefHeight(b);
		btnPoint.setPrefHeight(b);


		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(btn[7], 0, 0);
		GridPane.setConstraints(btn[8], 1, 0);
		GridPane.setConstraints(btn[9], 2, 0);
		GridPane.setConstraints(btn[4], 0, 1);
		GridPane.setConstraints(btn[5], 1, 1);
		GridPane.setConstraints(btn[6], 2, 1);
		GridPane.setConstraints(btn[1], 0, 2);
		GridPane.setConstraints(btn[2], 1, 2);
		GridPane.setConstraints(btn[3], 2, 2);
		GridPane.setConstraints(btn[0], 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(btn[0], btn[1], btn[2], btn[3], btn[4], btn[5], btn[6], btn[7], btn[8], btn[9],
				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);

		// 数字ボタンの機能
		for(int i = 0; i < 10; i++) {
			btn[i].setOnAction(event -> setLabelTest());
		}

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

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

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

	void setLabelTest() {
		//表示されている数字列が0だけの場合、1-9で上書きする。
		if(s1.equals("0")) {
			if(btn[1].isArmed()) {s1 = "1";}
			if(btn[2].isArmed()) {s1 = "2";}
			if(btn[3].isArmed()) {s1 = "3";}
			if(btn[4].isArmed()) {s1 = "4";}
			if(btn[5].isArmed()) {s1 = "5";}
			if(btn[6].isArmed()) {s1 = "6";}
			if(btn[7].isArmed()) {s1 = "7";}
			if(btn[8].isArmed()) {s1 = "8";}
			if(btn[9].isArmed()) {s1 = "9";}
		}else if(s1.matches("^[0-9, -]+$") && ope == ""){
			if(btn[0].isArmed()) {s1 += "0";}
			if(btn[1].isArmed()) {s1 += "1";}
			if(btn[2].isArmed()) {s1 += "2";}
			if(btn[3].isArmed()) {s1 += "3";}
			if(btn[4].isArmed()) {s1 += "4";}
			if(btn[5].isArmed()) {s1 += "5";}
			if(btn[6].isArmed()) {s1 += "6";}
			if(btn[7].isArmed()) {s1 += "7";}
			if(btn[8].isArmed()) {s1 += "8";}
			if(btn[9].isArmed()) {s1 += "9";}
			if(btnPlMi.isArmed()) {
				if(s1.substring(0,1).matches("-")) {
					s1 = s1.substring(1, s1.length());
				}else {
					s1 = "-" + s1;
				}
			}
		}
		if(ope == "") {
			if(btnPlus.isArmed()) {ope = "+";}
			if(btnMinus.isArmed()) {ope = "-";}
			if(btnMultiplied.isArmed()) {ope = "×";}
			if(btnDivided.isArmed()) {ope = "/";}
		}

		if(!ope.equals("")) {
			if(s2.equals("0")) {
				if(btn[1].isArmed()) {s2 = "1";}
				if(btn[2].isArmed()) {s2 = "2";}
				if(btn[3].isArmed()) {s2 = "3";}
				if(btn[4].isArmed()) {s2 = "4";}
				if(btn[5].isArmed()) {s2 = "5";}
				if(btn[6].isArmed()) {s2 = "6";}
				if(btn[7].isArmed()) {s2 = "7";}
				if(btn[8].isArmed()) {s2 = "8";}
				if(btn[9].isArmed()) {s2 = "9";}
			}else {
				if(btn[0].isArmed()) {s2 += "0";}
				if(btn[1].isArmed()) {s2 += "1";}
				if(btn[2].isArmed()) {s2 += "2";}
				if(btn[3].isArmed()) {s2 += "3";}
				if(btn[4].isArmed()) {s2 += "4";}
				if(btn[5].isArmed()) {s2 += "5";}
				if(btn[6].isArmed()) {s2 += "6";}
				if(btn[7].isArmed()) {s2 += "7";}
				if(btn[8].isArmed()) {s2 += "8";}
				if(btn[9].isArmed()) {s2 += "9";}
			}
		}

		if(!ope.equals("") && btnPlMi.isArmed() && !(s2.equals("0")) && !(s2.equals(""))) {
			System.out.println("a1");
			if(s2.matches("^[0-9]+$")) {
				s2 = "(" + "-" + s2 + ")";
			}else {
				s2 = s2.substring(2, s2.length() - 1);
			}
		}

		if(btnClear.isArmed()) {
			s1 = "0";
			s2 = "";
			ope = "";
		}
		label.setText(s1+ope+s2);
	}

	//計算機能 s1とs2の演算を行う
	void calc() {
		if(!(s2.matches("")) && !(ope.matches(""))) {
			if(!s2.matches("^[0-9]+$")) {
				s2 = s2.substring(1, s2.length() - 1);
			}
			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);
	}
}