【Swingアプリ開発】電卓アプリの解答例

2025-08-06

以下は、Swingを使用した基本的な電卓アプリケーションの完全な実装例です。四則演算(加減乗除)とクリア機能を備えています。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SimpleCalculator {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            // 電卓フレームの作成
            JFrame frame = new JFrame("簡単な電卓");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(300, 400);
            frame.setLayout(new BorderLayout(5, 5));

            // 計算結果表示用のテキストフィールド
            JTextField display = new JTextField();
            display.setEditable(false);
            display.setHorizontalAlignment(JTextField.RIGHT);
            display.setFont(new Font("Arial", Font.BOLD, 24));
            frame.add(display, BorderLayout.NORTH);

            // ボタンパネルの作成
            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(new GridLayout(4, 4, 5, 5));

            // 電卓ボタンのラベル
            String[] buttonLabels = {
                "7", "8", "9", "/",
                "4", "5", "6", "*",
                "1", "2", "3", "-",
                "C", "0", "=", "+"
            };

            // ボタンの作成と追加
            for (String label : buttonLabels) {
                JButton button = new JButton(label);
                button.setFont(new Font("Arial", Font.BOLD, 18));
                button.addActionListener(new CalculatorActionListener(display));
                buttonPanel.add(button);
            }

            frame.add(buttonPanel, BorderLayout.CENTER);
            frame.setVisible(true);
        });
    }
}

// 電卓のアクションリスナー
class CalculatorActionListener implements ActionListener {
    private JTextField display;
    private String firstNumber;
    private String operator;
    private boolean startNewNumber;

    public CalculatorActionListener(JTextField display) {
        this.display = display;
        this.firstNumber = "";
        this.operator = "";
        this.startNewNumber = true;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();

        if (command.charAt(0) >= '0' && command.charAt(0) <= '9') {
            // 数字ボタンが押された場合
            if (startNewNumber) {
                display.setText(command);
                startNewNumber = false;
            } else {
                display.setText(display.getText() + command);
            }
        } else if (command.equals("C")) {
            // クリアボタンが押された場合
            display.setText("0");
            firstNumber = "";
            operator = "";
            startNewNumber = true;
        } else if (command.equals("=")) {
            // イコールボタンが押された場合
            if (!operator.isEmpty() && !firstNumber.isEmpty()) {
                String secondNumber = display.getText();
                double result = calculate(
                    Double.parseDouble(firstNumber),
                    Double.parseDouble(secondNumber),
                    operator
                );
                display.setText(String.valueOf(result));
                operator = "";
                startNewNumber = true;
            }
        } else {
            // 演算子ボタンが押された場合
            if (!operator.isEmpty()) {
                // 既に演算子が選択されている場合は先に計算
                String secondNumber = display.getText();
                double result = calculate(
                    Double.parseDouble(firstNumber),
                    Double.parseDouble(secondNumber),
                    operator
                );
                display.setText(String.valueOf(result));
                firstNumber = String.valueOf(result);
            } else {
                firstNumber = display.getText();
            }
            operator = command;
            startNewNumber = true;
        }
    }

    // 計算を実行するメソッド
    private double calculate(double num1, double num2, String op) {
        switch (op) {
            case "+":
                return num1 + num2;
            case "-":
                return num1 - num2;
            case "*":
                return num1 * num2;
            case "/":
                if (num2 == 0) {
                    JOptionPane.showMessageDialog(display, "0で割ることはできません", "エラー", JOptionPane.ERROR_MESSAGE);
                    return num1;
                }
                return num1 / num2;
            default:
                return num2;
        }
    }
}

この電卓アプリの特徴

  1. 基本機能:
  • 数字入力(0-9)
  • 四則演算(+, -, *, /)
  • クリア機能(C)
  • 計算実行(=)
  1. UI構成:
  • 上部に計算結果表示用のテキストフィールド
  • 4x4のボタン配置(数字、演算子、クリア、イコール)
  1. 動作ロジック:
  • 数字ボタンで数値を入力
  • 演算子ボタンで計算方法を選択
  • イコールボタンで計算実行
  • クリアボタンでリセット

拡張可能なポイント

この基本実装をさらに発展させるためのアイデア:

  1. 追加機能:
  • 小数点ボタンの実装
  • パーセント計算機能
  • メモリ機能(M+, M-, MR, MC)
  1. UI改善:
  • ボタンの色分け(数字と演算子で色を変更)
  • ボタンのサイズ調整
  • キーボード入力のサポート
  1. エラー処理の強化:
  • オーバーフロー時の処理
  • 無効な入力への対応
  1. コードの改良:
  • 状態管理をStateパターンで実装
  • 計算ロジックを別クラスに分離

例えば、小数点ボタンを追加するには以下のように変更できます:

// ボタンラベルに小数点を追加
String[] buttonLabels = {
    "7", "8", "9", "/",
    "4", "5", "6", "*",
    "1", "2", "3", "-",
    "C", "0", ".", "+",
    "="  // イコールボタンを別の行に移動
};

// actionPerformedメソッドに小数点処理を追加
if (command.equals(".")) {
    if (startNewNumber) {
        display.setText("0.");
        startNewNumber = false;
    } else if (!display.getText().contains(".")) {
        display.setText(display.getText() + ".");
    }
}

この電卓アプリはSwingの基本的なコンポーネントとイベント処理を理解するのに最適なサンプルです。まずはこの基本形を理解し、その後で機能拡張に挑戦してみてください。