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

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

JavaFX で電卓を作る その4

JavaFXで電卓を作る

随分前に投げ出していたJavaFXの電卓アプリを作っていきます。

f:id:yamakasa3:20180716012405p:plain

前回までの電卓では、整数も「3 × 6 = 18.0」のように、小数点が含まれていましたが、今回はそれを改良しました。

f:id:yamakasa3:20180716011403p:plain

次回は小数点の入力できるようにします。

久しぶりにコードを見たら酷いですね・・・。

コード

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(""))) {
            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);
                if(result == (int)result) {
                    label.setText(String.valueOf((int)result));
                }else {
                    label.setText(String.valueOf(result));
                }
            }else if(ope.equals("-") && (s2.matches("^[0-9, -]+$"))){
                result = Double.valueOf(s1) -  Double.valueOf(s2);
                if(result == (int)result) {
                    label.setText(String.valueOf((int)result));
                }else {
                    label.setText(String.valueOf(result));
                }
            }else if(ope.equals("×") && (s2.matches("^[0-9, -]+$"))){
                result = Double.valueOf(s1) *  Double.valueOf(s2);
                if(result == (int)result) {
                    label.setText(String.valueOf((int)result));
                }else {
                    label.setText(String.valueOf(result));
                }
            }else if(ope.equals("/") && (s2.matches("^[0-9, -]+$"))){
                result = Double.valueOf(s1) /  Double.valueOf(s2);
                if(result == (int)result) {
                    label.setText(String.valueOf((int)result));
                }else {
                    label.setText(String.valueOf(result));
                }
            }
        }
    }

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