argius note

プログラミング関連

JavaFX8で電卓を作ってみた

題名の通り。今回は短編です。
要約すると、「VB感覚でGUIアプリが作れるようになってスゴイ!」です。

コードだけ見たい方は、Gistに登録したのでそちらをどうぞ。
Calculator written in Java 8 with JavaFX 8 + SceneBuilder 2.0


見た目はこんな感じ。

f:id:argius:20150111145434p:plain

レイアウトや見栄えは、Javaコードに触れることなく*1、後でゆっくり自分の好みで変えていけます。


最低限の機能しか無いとはいえ、Javaは100行未満で出来てしまいました。

Java以外のファイルは、前述したGistに全部アップしてます。

  • App.java
package net.argius.calculator;

import java.math.BigDecimal;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public final class App extends Application {

    private BigDecimal left;
    private String selectedOperator;
    private boolean numberInputting;

    @FXML
    private TextField display;

    public App() {
        this.left = BigDecimal.ZERO;
        this.selectedOperator = "";
        this.numberInputting = false;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("Calculator");
        stage.setOnCloseRequest(x -> {
            Platform.exit();
        });
        stage.setResizable(false);
        stage.setScene(new Scene(FXMLLoader.load(getClass().getResource("main.fxml"))));
        stage.show();
    }

    @FXML
    protected void handleOnAnyButtonClicked(ActionEvent evt) {
        Button button = (Button)evt.getSource();
        final String buttonText = button.getText();
        if (buttonText.equals("C") || buttonText.equals("AC")) {
            if (buttonText.equals("AC")) {
                left = BigDecimal.ZERO;
            }
            selectedOperator = "";
            numberInputting = false;
            display.setText("0");;
            return;
        }
        if (buttonText.matches("[0-9\\.]")) {
            if (!numberInputting) {
                numberInputting = true;
                display.clear();
            }
            display.appendText(buttonText);
            return;
        }
        if (buttonText.matches("[+-×÷]")) {
            left = new BigDecimal(display.getText());
            selectedOperator = buttonText;
            numberInputting = false;
            return;
        }
        if (buttonText.equals("=")) {
            final BigDecimal right = numberInputting ? new BigDecimal(display.getText()) : left;
            left = calculate(selectedOperator, left, right);
            display.setText(left.toString());
            numberInputting = false;
            return;
        }
    }

    static BigDecimal calculate(String operator, BigDecimal left, BigDecimal right) {
        switch (operator) {
            case "+":
                return left.add(right);
            case "-":
                return left.subtract(right);
            case "×":
                return left.multiply(right);
            case "÷":
                return left.divide(right);
            default:
        }
        return right;
    }

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

}

電卓だから国際化は無くても良いのでやってません。通常のアプリだとテキストを外部リソースにすることも必要になってきますね。
全世界向けじゃなければそこまで考えなくても良いでしょうし。


Java7以前だと、NetBeansEclipseプラグインを使ってSwingでがんばっていたところが、JavaFX8だとがんばらなくて良くなりました。

完全にVB感覚*2で作れますね。

さようならSwing。


(おわり)

*1:少し手を加えないといけないケースもあるかもしれませんが。

*2:古い?今はC#かな?