BMI。4、BMI 計算機(AWT GUI コンポーネント版)


BMI 計算機です。
Java GUI プログラミングの秀作、Javadoc 生成、プログラミング作法の取り入れ、等々。
色々やってたら期間やらソース量やら上昇してしまいましたが、
現状納得行くカタチに持ってけたかと思うので公開しておきます。


BmiCalculator.jar



プロジェクトは Eclipse のデフォルト設定でのものです。
リソースの読み込みにその辺りの片鱗が垣間見れたりします。


以下のソースは参考までに。
実際に動かしてみたりプロジェクト一式覗いてみたい方は、
上のリンクから JAR ファイルがダウンロードできるようになってますので。


プロジェクト構成

./Main.java
./jp/regekatsu/gui/AboutDialog.java
./jp/regekatsu/gui/MainFrame.java
./jp/regekatsu/gui/package-info.java
./jp/regekatsu/gui/resources/graphics/banner.png
./jp/regekatsu/gui/resources/graphics/icon.png
./jp/regekatsu/language/package-info.java
./jp/regekatsu/language/Text.java
./jp/regekatsu/utility/Bmi.java
./jp/regekatsu/utility/package-info.java
./jp/regekatsu/utility/Sex.java


./Main.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : テンプレート
 * 業務名     : メイン
 * 概要       : メインの雛形。最初に実行される処理を記述する
 */

import jp.regekatsu.gui.MainFrame;

/**
 * このクラスは main メソッドを含んでおり、プログラムの最初に実行されます。
 *
 * @author DumBo
 * @since 0.01(Jul 13, 2012)
 * @version 0.01(Jul 13, 2012)
 */
class Main {

	/**
	 * メインメソッドの定義です。
	 * このメソッドはプログラムの最初に実行されます。
	 *
	 * @param args プログラム実行時に渡されるパラメータ
	 */
	public static void main(String[] args) {
		new MainFrame();
	}

}


./jp/regekatsu/gui/AboutDialog.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : ライブラリ
 * 業務名     : アバウトダイアログ
 * 概要       : バージョン情報ダイアログを提供する
 */

package jp.regekatsu.gui;

import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * AboutDialog クラスは、バージョン情報ダイアログを提供します。
 *
 * @author DumBo
 * @since 0.01(Jul 13, 2012))
 * @version 0.01(Jul 13, 2012)
 */
public class AboutDialog extends Dialog implements ActionListener, MouseListener {

	/** シリアライズバージョン */
	private static final long serialVersionUID = 1L;

	/** ダイアログタイトル */
	private static final String ABOUT_DIALOG_TITLE = "バージョン情報";

	/** アプリケーション名ラベル */
	private Label nameLabel;
	/** バージョン情報ラベル */
	private Label versionLabel;
	/** 公開情報ラベル */
	private Label releaseLabel;

	/** アイコンイメージ */
	private Image iconImage;
	/** バナーイメージ */
	private Image bannerImage;

	/** コピーライトラベル */
	private Label copyrightLabel;
	/** インターネットアドレス */
	private String url;
	/** ハイパーリンク設定 */
	private boolean isHyperLink;
	/** デスクトップ情報 */
	private Desktop currentDesktop = Desktop.getDesktop();

	/** OK ボタン */
	private Button okButton;


	/**
	 * 指定されたフレームを親フレームとして、モーダルなバージョン情報ダイアログを作成します。
	 *
	 * @param owner 指定されたフレーム
	 */
	public AboutDialog(Frame owner) {

		// ダイアログの、親フレーム設定、及びモーダルを有効化
		super(owner, true);

		// ダイアログのタイトル
		setTitle(ABOUT_DIALOG_TITLE);

		// ダイアログのレイアウト
		setLayout(null);

		// ダイアログのサイズ
		setSize(320, 180);

		// ダイアログのサイズを固定
		setResizable(false);

		// ダイアログの表示位置を親フレーム中央に設定
		setLocationRelativeTo(owner);

		// ダイアログの背景色
		setBackground(Color.LIGHT_GRAY);

		// アプリケーション名ラベルの設定
		nameLabel = new Label("", Label.LEFT);
		nameLabel.setBounds(70, 40, 130, 15);
		add(nameLabel);

		// バージョン情報ラベルの設定
		versionLabel = new Label("", Label.LEFT);
		versionLabel.setBounds(70, 55, 130, 15);
		add(versionLabel);

		// 公開日ラベルの設定
		releaseLabel = new Label("", Label.LEFT);
		releaseLabel.setBounds(70, 70, 130, 15);
		add(releaseLabel);

		// コピーライトラベルの設定
		copyrightLabel = new Label("", Label.LEFT);
		copyrightLabel.setBounds(30, 150, 250, 15);
		copyrightLabel.addMouseListener(this);
		add(copyrightLabel);

		// インターネットアドレスの設定
		url = "";
		// ハイパーリンク設定を無効に設定
		isHyperLink = false;

		// OK ボタンの設定
		okButton = new Button("OK");
		okButton.setBounds(220, 40, 80, 20);
		okButton.addActionListener(this);
		add(okButton);

		// ダイアログを閉じる
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				setVisible(false);
			}
		});

	}

	/**
	 * アプリケーション名として表示される名前を、指定された文字列に設定します。
	 *
	 * @param name アプリケーション名に表示される名前。null 値は空の文字列""として扱われる
	 */
	@Override
	public void setName(String name) {
		if(name == null || name == "") {
			setTitle(ABOUT_DIALOG_TITLE);
		} else {
			setTitle(name + "の" + ABOUT_DIALOG_TITLE);
		}
		nameLabel.setText(name);
	}

	/**
	 * バージョン情報として表示される内容を、指定された文字列に設定します。
	 *
	 * @param version バージョン情報に表示される内容。null 値は空の文字列""として扱われる
	 */
	public void setVersion(String version) {
		versionLabel.setText(version);
	}

	/**
	 * 公開情報として表示される内容を、指定された文字列に設定します。
	 *
	 * @param release 公開情報に表示される内容。null 値は空の文字列""として扱われる
	 */
	public void setRelease(String release) {
		releaseLabel.setText(release);
	}

	/**
	 * バナーとして表示されるイメージを設定します。
	 *
	 * @param bannerImage 表示されるバナーイメージ
	 */
	public void setBannerImage(Image bannerImage) {
		this.bannerImage = bannerImage;
	}

	/**
	 * アプリケーションアイコンとして表示されるイメージを設定します。
	 *
	 * @param iconImage 表示されるアプリケーションアイコンイメージ
	 */
	@Override
	public void setIconImage(Image iconImage) {
		this.iconImage = iconImage;
	}

	/**
	 * コピーライトとして表示される内容を、指定された文字列に設定します。
	 *
	 * @param copyright コピーライトに表示される内容。null 値は空の文字列""として扱われる
	 */
	public void setCopyright(String copyright) {
		copyrightLabel.setText(copyright);
	}

	/**
	 * コピーライトにハイパーリンクされるインターネットアドレスを、
	 * 指定された文字列に設定します。
	 *
	 * @param url コピーライトにハイパーリンクされるインターネットアドレス。
	 * null 値は空の文字列""として扱われる
	 */
	public void setUrl(String url) {
		this.url = (url == null) ? "":url;
	}

	/**
	 * パラメータ isHyperLink に応じて、コピーライトにハイパーリンクされるインターネットアドレスを、
	 * 有効にするか、または無効にします。
	 *
	 * @param isHyperLink true の場合はハイパーリンクを有効にし、
	 * そうでない場合はハイパーリンクを無効にする
	 */
	public void setHyperLink(boolean isHyperLink) {
		this.isHyperLink = isHyperLink;
		repaint();
	}

	/**
	 * 指定されたコンポーネント c との相対位置で、ダイアログの位置を設定し、
	 * パラメータ b の値に応じて、このコンポーネントを中央表示するか、または非表示にします。
	 * 現在、指定されたコンポーネントが表示されていない場合は、
	 * ダイアログは画面の中央に配置されます。
	 *
	 * @param c
	 *            ダイアログの位置の基準となるコンポーネント
	 * @param b
	 *            true の場合このコンポーネントを中央表示し、
	 *            そうでない場合はこのコンポーネントを隠す
	 */
	public void setVisible(Component c, boolean b) {
		setLocationRelativeTo(c);
		setVisible(b);
	}

	/**
	 * ダイアログウィンドウ描画の定義です。
	 * 描画要求が発生すると、このメソッドで定義した動作が、
	 * repaint メソッドとして自動的に呼び出されます。
	 */
	@Override
	public void paint(Graphics g) {
		// アイコンイメージ、バナーイメージの描画
		g.drawImage(iconImage, 20, 40, this);
		g.drawImage(bannerImage, 60, 100, this);

		//ハイパーリンクが有効ならコピーライトラベルを青にして、下線を貼る
		if(!isHyperLink) {
			return;
		}
		copyrightLabel.setForeground(Color.blue);
		g.setColor(Color.blue);
		g.drawLine(30, 165, 275, 165);
	}

	/**
	 * アクションイベントの定義です。
	 * アクションイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void actionPerformed(ActionEvent e) {
		// OK ボタンが押されたら、ダイアログを非表示にする
		setVisible(false);
	}

	/**
	 * コンポーネント上でマウスボタンをクリックしたときの定義です。
	 * マウスイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void mouseClicked(MouseEvent e) {
		// ハイパーリンク有効時、コピーライトラベルがクリックされたら、
		// デフォルトブラウザで、インターネットアドレスを開く
		if(!isHyperLink) {
			return;
		}
		try {
			browseUri();
		} catch (URISyntaxException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * コンポーネントにマウスが入るときの定義です。
	 * マウスイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void mouseEntered(MouseEvent e) {
		 // ハイパーリンク有効時、マウスがコピーライトラベルに入ったら、
		 // カーソルイメージを手の画像のものに変更する
		if(!isHyperLink) {
			return;
		}
		setCursor(new Cursor(Cursor.HAND_CURSOR));
	}

	/**
	 * コンポーネントからマウスが出るときの定義です。
	 * マウスイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void mouseExited(MouseEvent e) {
		 // ハイパーリンク有効時、マウスがコピーライトラベルから出たら、
		 // カーソルイメージを標準のものに変更する
		if(!isHyperLink) {
			return;
		}
		setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
	}

	/**
	 * コンポーネント上でマウスボタンが押されるときの定義です。
	 * マウスイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void mousePressed(MouseEvent e) {
	}

	/**
	 * コンポーネント上でマウスボタンが離されるときの定義です。
	 * マウスイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void mouseReleased(MouseEvent e) {
	}

	/**
	 * デフォルトブラウザで、インターネットアドレスを開きます。
	 *
	 * @throws URISyntaxException
	 *             文字列を URI 参照として解析できなかった場合
	 *             (文字列に半角スペースが含まれてた場合など)
	 * @throws IOException
	 *             入出力エラーが発生した場合
	 *             (文字列にパスに用いない文字が含まれてた場合など)
	 */
	private void browseUri() throws URISyntaxException, IOException {
		currentDesktop.browse(new URI(url));
	}

}


./jp/regekatsu/gui/MainFrame.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : テンプレート
 * 業務名     : メインフレーム
 * 概要       : メインフレームの雛形。ここに任意の記述を行いメインフレームを構築する
 */

package jp.regekatsu.gui;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Label;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.math.BigDecimal;
import java.net.URL;
import jp.regekatsu.language.Text;
import jp.regekatsu.utility.Bmi;
import jp.regekatsu.utility.Sex;

/**
 * MainFrame クラスは、main メソッドから呼び出して利用する、
 * アプリケーションのメインフレームです。
 *
 * @author DumBo
 * @since 0.01(Jul 13, 2012)
 * @version 0.01(Jul 13, 2012)
 */
public class MainFrame extends Frame implements ActionListener {

	/** シリアライズバージョン */
	private static final long serialVersionUID = 1L;

	/** フレームタイトル */
	private static final String MAIN_FRAME_TITLE = "BMI 計算機";

	/** アプリケーション名 */
	private static final String ABOUT_DIALOG_NAME = MAIN_FRAME_TITLE;
	/** バージョン情報 */
	private static final String ABOUT_DIALOG_VERSION = "version 0.01";
	/** 公開情報 */
	private static final String ABOUT_DIALOG_RELEASE = "Jul 13, 2012";
	/** コピーライト */
	private static final String ABOUT_DIALOG_COPYRIGHT = "(c) 2012 DumBoさんの Homebrew 開発日記";
	/** インターネットアドレス */
	private static final String ABOUT_DIALOG_URL = "http://d.hatena.ne.jp/dumbo001/";

	/** アプリケーションが開始された際の表記 */
	private static final String MESSAGE_WELCOME = "あなたの BMI を計算します。";
	/** 情報が全て入力されてない際の表記 */
	private static final String MESSAGE_IS_EMPTY = "情報は全て入力してください。";
	/** 身長、体重が数値で入力されてなかった際の表記 */
	private static final String MESSAGE_IS_STRING = "身長、体重は数値を入力してください。";
	/** 身長、体重が0より大きい数を指定してなかった場合の表記 */
	private static final String MESSAGE_IS_LESS = "0より大きい数を入れてください。";
	/** 計算結果を出した際の表記 */
	private static final String MESSAGE_ANSWER = "計算結果を表示します。";

	/** 判定結果が「やせ」となった際の回答 */
	private static final String JUDGE_ANSWER_SLENDER = "すごく…細いです…";
	/** 判定結果が「標準」となった際の回答 */
	private static final String JUDGE_ANSWER_STANDARD = "ちょうど…良いです…";
	/** 判定結果が「過体重」となった際の回答 */
	private static final String JUDGE_ANSWER_PLUMP = "すこし…太いです…";
	/** 判定結果が「肥満」となった際の回答 */
	private static final String JUDGE_ANSWER_FAT = "すごく…太いです…";

	/** アイコンイメージファイル */
	private static final String ICON_FILE = "resources/graphics/icon.png";
	/** アイコンイメージ URL */
	private URL iconUrl;
	/** アイコンイメージ */
	private Image iconImage;

	/** バナーイメージファイル */
	private static final String BANNER_FILE = "resources/graphics/banner.png";
	/** バナーイメージ URL */
	private URL bannerUrl;
	/** バナーイメージ */
	private Image bannerImage;

	/** メニューバー */
	private MenuBar mainFrameMenuBar;

	/** ファイルメニュー */
	private Menu fileMenu;
	/** 編集メニュー */
	private Menu editMenu;
	/** ヘルプメニュー */
	private Menu helpMenu;

	/** ファイルメニュー - 終了メニューアイテム */
	private MenuItem exitFileMenuItem;
	/** 編集メニュー - 計算メニューアイテム */
	private MenuItem calculateEditMenuItem;
	/** 編集メニュー - リセットメニューアイテム */
	private MenuItem resetEditMenuItem;
	/** ヘルプメニュー - バージョン情報メニューアイテム */
	private MenuItem aboutDialogHelpMenuItem;

	/** メッセージラベル */
	private Label messageLabel;
	/** 名前ラベル */
	private Label nameLabel;
	/** 性別ラベル */
	private Label sexLabel;
	/** 身長ラベル */
	private Label heightLabel;
	/** 身長(cm)ラベル */
	private Label heightCmLabel;
	/** 体重ラベル */
	private Label weightLabel;
	/** 体重(kg)ラベル */
	private Label weightKgLabel;

	/** BMI ラベル */
	private Label bmiLabel;
	/** BMI 判定ラベル */
	private Label bmiAnswerLabel;
	/** 理想 BMI ラベル */
	private Label idealBmiLabel;
	/** 理想 BMI 回答ラベル */
	private Label idealBmiAnswerLabel;
	/** 理想体重ラベル */
	private Label idealWeightLabel;
	/** 理想体重回答ラベル */
	private Label idealWeightAnswerLabel;
	/** 摂取カロリーラベル */
	private Label necessaryCaloryLabel;
	/** 摂取カロリー回答ラベル */
	private Label necessaryCaloryAnswerLabel;
	/** 判定前置きラベル */
	private Label judgeIntroLabel;
	/** 判定回答ラベル */
	private Label judgeAnswerLabel;

	/** 名前テキストフィールド */
	private TextField nameTextField;
	/** 身長テキストフィールド */
	private TextField heightTextField;
	/** 体重テキストフィールド */
	private TextField weightTextField;

	/** 性別チョイス */
	private Choice sexChoice;

	/** 計算ボタン */
	private Button calculateButton;
	/** リセットボタン */
	private Button resetButton;

	/** バージョン情報ダイアログ */
	private AboutDialog aboutDialog;
	/** BMI オブジェクト */
	private Bmi bmi;

	/**
	 * 新規メインフレームを作成します。
	 */
	public MainFrame() {

		/* フレーム 外枠定義 */

		// アイコンイメージの URL 読み込み
		iconUrl = this.getClass().getResource(ICON_FILE);
		// アイコンイメージの読み込み
		iconImage = (iconUrl != null) ? getToolkit().getImage(iconUrl)
			:getToolkit().getImage(ICON_FILE);

		// バナーイメージの URL 読み込み
		bannerUrl = this.getClass().getResource(BANNER_FILE);
		// バナーイメージの読み込み
		bannerImage = (bannerUrl != null) ? getToolkit().getImage(bannerUrl)
			:getToolkit().getImage(BANNER_FILE);

		// フレーム タイトルの設定
		setTitle(MAIN_FRAME_TITLE);

		// フレーム レイアウト
		setLayout(null);

		// フレーム サイズ
		setSize(250, 360);

		// フレーム サイズを固定
		setResizable(false);

		// フレーム 表示位置を画面中央に設定
		setLocationRelativeTo(null);

		// フレーム 背景色
		setBackground(Color.LIGHT_GRAY);

		// フレーム アイコンの設定
		setIconImage(iconImage);

		// フレーム 表示
		setVisible(true);

		// フレーム 閉じる
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		/* フレーム 内側定義 */

		// メニューバー 生成
		mainFrameMenuBar = new MenuBar();

		// ファイルメニュー 生成
		fileMenu = new Menu("ファイル");

		// ファイルメニュー−終了メニューアイテム 生成と設定
		exitFileMenuItem = new MenuItem("終了");
		exitFileMenuItem.addActionListener(this);
		fileMenu.add(exitFileMenuItem);

		// ファイルメニュー 貼り付け
		mainFrameMenuBar.add(fileMenu);

		// 編集メニュー 生成
		editMenu = new Menu("編集");

		// 編集メニュー−計算メニューアイテム 生成と設定
		calculateEditMenuItem = new MenuItem("計算");
		calculateEditMenuItem.addActionListener(this);
		editMenu.add(calculateEditMenuItem);

		// 編集メニュー−リセットメニューアイテム 生成と設定
		resetEditMenuItem = new MenuItem("リセット");
		resetEditMenuItem.addActionListener(this);
		editMenu.add(resetEditMenuItem);

		// 編集メニュー 貼り付け
		mainFrameMenuBar.add(editMenu);

		// ヘルプメニュー 生成
		helpMenu = new Menu("ヘルプ");

		// ヘルプメニュー−バージョン情報メニューアイテム 生成と設定
		aboutDialogHelpMenuItem = new MenuItem("バージョン情報");
		aboutDialogHelpMenuItem.addActionListener(this);
		helpMenu.add(aboutDialogHelpMenuItem);

		// ヘルプメニュー 貼り付け
		mainFrameMenuBar.add(helpMenu);

		// メニューバー 貼り付け
		this.setMenuBar(mainFrameMenuBar);

		// メッセージラベル 生成と設定
		messageLabel = new Label(MESSAGE_WELCOME, Label.CENTER);
		messageLabel.setBounds(0, 50, 250, 20);
		add(messageLabel);

		// 名前ラベル 生成と設定
		nameLabel = new Label("名前 :", Label.RIGHT);
		nameLabel.setBounds(20, 80, 80, 20);
		add(nameLabel);

		// 性別ラベル 生成と設定
		sexLabel = new Label("性別 :", Label.RIGHT);
		sexLabel.setBounds(20, 105, 80, 20);
		add(sexLabel);

		// 身長ラベル 生成と設定
		heightLabel = new Label("身長 :", Label.RIGHT);
		heightLabel.setBounds(20, 130, 80, 20);
		add(heightLabel);

		// 体重ラベル 生成と設定
		weightLabel = new Label("体重 :", Label.RIGHT);
		weightLabel.setBounds(20, 155, 80, 20);
		add(weightLabel);

		// 名前テキストフィールド 生成と設定
		nameTextField = new TextField();
		nameTextField.setBounds(110, 80, 100, 20);
		add(nameTextField);

		// 性別チョイス 生成と設定
		sexChoice = new Choice();
		sexChoice.setBounds(110, 105, 60, 20);
		sexChoice.add("男性");
		sexChoice.add("女性");
		add(sexChoice);

		// 身長テキストフィールド 生成と設定
		heightTextField = new TextField();
		heightTextField.setBounds(110, 130, 80, 20);
		add(heightTextField);

		// 体重テキストフィールド 生成と設定
		weightTextField = new TextField();
		weightTextField.setBounds(110, 155, 80, 20);
		add(weightTextField);

		// 身長(cm)ラベル 生成と設定
		heightCmLabel = new Label("cm", Label.LEFT);
		heightCmLabel.setBounds(200, 130, 20, 20);
		add(heightCmLabel);

		// 体重(kg)ラベル 生成と設定
		weightKgLabel = new Label("kg", Label.LEFT);
		weightKgLabel.setBounds(200, 155, 20, 20);
		add(weightKgLabel);

		// 計算ボタン 生成と設定
		calculateButton = new Button("計算");
		calculateButton.setBounds(30, 190, 80, 20);
		calculateButton.addActionListener(this);
		add(calculateButton);

		// リセットボタン 生成と設定
		resetButton = new Button("リセット");
		resetButton.setBounds(130, 190, 80, 20);
		resetButton.addActionListener(this);
		add(resetButton);

		// BMI ラベル 生成と設定
		bmiLabel = new Label("BMI :", Label.RIGHT);
		bmiLabel.setBounds(20, 225, 80, 20);
		add(bmiLabel);

		// 理想 BMI ラベル 生成と設定
		idealBmiLabel = new Label("理想 BMI :", Label.RIGHT);
		idealBmiLabel.setBounds(20, 245, 80, 20);
		add(idealBmiLabel);

		// 理想体重ラベル 生成と設定
		idealWeightLabel = new Label("理想体重 :", Label.RIGHT);
		idealWeightLabel.setBounds(20, 265, 80, 20);
		add(idealWeightLabel);

		// 摂取カロリーラベル 生成と設定
		necessaryCaloryLabel = new Label("摂取カロリー :", Label.RIGHT);
		necessaryCaloryLabel.setBounds(20, 285, 80, 20);
		add(necessaryCaloryLabel);

		// BMI 回答ラベル 生成と設定
		bmiAnswerLabel = new Label("", Label.LEFT);
		bmiAnswerLabel.setBounds(110, 225, 80, 20);
		add(bmiAnswerLabel);

		// 理想 BMI 回答ラベル 生成と設定
		idealBmiAnswerLabel = new Label("", Label.LEFT);
		idealBmiAnswerLabel.setBounds(110, 245, 80, 20);
		add(idealBmiAnswerLabel);

		// 理想体重回答ラベル 生成と設定
		idealWeightAnswerLabel = new Label("", Label.LEFT);
		idealWeightAnswerLabel.setBounds(110, 265, 80, 20);
		add(idealWeightAnswerLabel);

		// 摂取カロリー回答ラベル 生成と設定
		necessaryCaloryAnswerLabel = new Label("", Label.LEFT);
		necessaryCaloryAnswerLabel.setBounds(110, 285, 80, 20);
		add(necessaryCaloryAnswerLabel);

		// 判定前置きラベル 生成と設定
		judgeIntroLabel = new Label("", Label.CENTER);
		judgeIntroLabel.setBounds(0, 315, 250, 15);
		add(judgeIntroLabel);
		// 判定回答ラベル 生成と設定
		judgeAnswerLabel = new Label("", Label.CENTER);
		judgeAnswerLabel.setBounds(0, 330, 250, 15);
		add(judgeAnswerLabel);

		/* バージョン情報ダイアログ 定義 */

		// バージョン情報ダイアログ 初期化
		aboutDialog = new AboutDialog(this);

		// バージョン情報ダイアログ アプリケーション名を設定
		aboutDialog.setName(ABOUT_DIALOG_NAME);

		// バージョン情報ダイアログ バージョン情報を設定
		aboutDialog.setVersion(ABOUT_DIALOG_VERSION);

		// バージョン情報ダイアログ 公開情報を設定
		aboutDialog.setRelease(ABOUT_DIALOG_RELEASE);

		// バージョン情報ダイアログ アプリケーションアイコンイメージを設定
		aboutDialog.setIconImage(iconImage);

		// バージョン情報ダイアログ バナーイメージを設定
		aboutDialog.setBannerImage(bannerImage);

		// バージョン情報ダイアログ コピーライトを設定
		aboutDialog.setCopyright(ABOUT_DIALOG_COPYRIGHT);

		// バージョン情報ダイアログ インターネットアドレスを設定
		aboutDialog.setUrl(ABOUT_DIALOG_URL);

		// バージョン情報ダイアログ ハイパーリンクを有効にする
		aboutDialog.setHyperLink(true);

		// バージョン情報ダイアログ ダイアログ初期状態を非表示に設定
		//aboutDialog.setVisible(false);

		/* BMI オブジェクト 定義 */

		// BMI オブジェクト 初期化
		bmi = new Bmi();

	}

	/**
	 * アクションイベントの定義です。
	 * アクションイベントが発生すると、このメソッドが自動的に呼び出されます。
	 */
	public void actionPerformed(ActionEvent e) {

		Object object = e.getSource();

		// 終了を実行する
		if (object == exitFileMenuItem) {
			executeExit();

		// 計算を実行する
		} else if (object == calculateEditMenuItem || object == calculateButton) {
			executeCalculate();

		// リセットを実行する
		} else if (object == resetEditMenuItem || object == resetButton) {
			executeReset();

		// バージョン情報ダイアログの表示を実行する
		} else if (object == aboutDialogHelpMenuItem) {
			executeAboutDialog();

		}

	}

	/**
	 * プログラムを終了します。
	 */
	private void executeExit() {
		System.exit(0);
	}

	/**
	 * BMI を計算して、結果をフォーム上部と下部に表示します。
	 */
	private void executeCalculate() {

		// 情報が全て入力してあるか確認する
		if(nameTextField.getText().length() == 0 || heightTextField.getText().length() == 0
			|| weightTextField.getText().length() == 0) {

			messageLabel.setForeground(Color.red);
			messageLabel.setText(MESSAGE_IS_EMPTY);
			return;
		}

		// 身長、体重は数値が入力されてるか確認する
		if(Text.isRealNumber(heightTextField.getText()) == false
				|| Text.isRealNumber(weightTextField.getText()) == false) {

			messageLabel.setForeground(Color.red);
			messageLabel.setText(MESSAGE_IS_STRING);
			return;
		}
		double height = Double.parseDouble(heightTextField.getText());
		double weight = Double.parseDouble(weightTextField.getText());

		// 身長、体重は0より大きい数を指定してるか確認する
		if(height <= 0.0d || weight <= 0.0d) {
			messageLabel.setForeground(Color.red);
			messageLabel.setText(MESSAGE_IS_LESS);
			return;
		}

		// 入力値をセットする
		bmi.setSex((sexChoice.getSelectedIndex() == Sex.MALE.ordinal()) ? Sex.MALE:Sex.FEMALE);
		bmi.setHeight(Double.parseDouble(heightTextField.getText()));
		bmi.setWeight(Double.parseDouble(weightTextField.getText()));

		// 計算結果を、小数点第二位で切り捨てた状態で取得する
		BigDecimal bmiAnswer             = new BigDecimal(bmi.getBmi());
		BigDecimal idealBmiAnswer        = new BigDecimal(bmi.getIdealBmi());
		BigDecimal idealWeightAnswer     = new BigDecimal(bmi.getIdealWeight());
		BigDecimal necessaryCaloryAnswer = new BigDecimal(bmi.getNecessaryCalory());

		// 計算結果を表示する
		messageLabel.setForeground(Color.blue);
		messageLabel.setText(MESSAGE_ANSWER);

		bmiAnswerLabel.setText(String.valueOf(bmiAnswer
				.setScale(1, BigDecimal.ROUND_DOWN).doubleValue()));
		idealBmiAnswerLabel.setText(String.valueOf(idealBmiAnswer
				.setScale(1, BigDecimal.ROUND_DOWN).doubleValue()));
		idealWeightAnswerLabel.setText(String.valueOf(idealWeightAnswer
				.setScale(1, BigDecimal.ROUND_DOWN).doubleValue()) + " kg");
		necessaryCaloryAnswerLabel.setText(String.valueOf(necessaryCaloryAnswer
				.setScale(1, BigDecimal.ROUND_DOWN).doubleValue()) + " cal");

		// 計算結果に基づいた判定回答を表示する
		int judge = bmi.getJudge();
		String judgeAnswer;

		switch(judge) {
		case Bmi.JUDGE_SLENDER:
			judgeAnswer = JUDGE_ANSWER_SLENDER;
			break;
		case Bmi.JUDGE_STANDARD:
			judgeAnswer = JUDGE_ANSWER_STANDARD;
			break;
		case Bmi.JUDGE_PLUMP:
			judgeAnswer = JUDGE_ANSWER_PLUMP;
			break;
		case Bmi.JUDGE_FAT:
			judgeAnswer = JUDGE_ANSWER_FAT;
			break;
		default:
			throw new IllegalArgumentException("予期しない例外が発生しました。");
		}
		judgeIntroLabel.setText(nameTextField.getText() + "さんの判定は…");
		judgeAnswerLabel.setText(judgeAnswer);

	}

	/**
	 * 結果表示と、入力値の内容をリセットします。
	 */
	private void executeReset() {
		messageLabel.setForeground(Color.black);
		messageLabel.setText(MESSAGE_WELCOME);

		nameTextField.setText("");
		heightTextField.setText("");
		weightTextField.setText("");
		sexChoice.select(0);
		bmiAnswerLabel.setText("");
		idealBmiAnswerLabel.setText("");
		idealWeightAnswerLabel.setText("");
		necessaryCaloryAnswerLabel.setText("");
		judgeIntroLabel.setText("");
		judgeAnswerLabel.setText("");
	}

	/**
	 * バージョン情報ダイアログの表示を行います。
	 */
	private void executeAboutDialog() {
		// 親フレームを基準として、ダイアログを中央に配置、表示する
		aboutDialog.setVisible(this, true);
	}

}


./jp/regekatsu/gui/package-info.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : パッケージ
 * 業務名     : グラフィカルユーザインターフェイス(GUI)
 * 概要       : パッケージの概要説明
 */

/**
* Java GUI プログラム言語の設計にあたり、補助的なクラスを提供します。
 *
 * @author DumBo
 * @since 0.01(Jul 13, 2012)
 * @version 0.01(Jul 13, 2012)
*/
package jp.regekatsu.gui;


./jp/regekatsu/language/package-info.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : パッケージ
 * 業務名     : ランゲージ
 * 概要       : パッケージの概要説明
 */

/**
* Java プログラム言語の設計にあたり、コアパッケージに含まれない
* 基本的なクラスを提供します。
*
 * @author DumBo
 * @since 0.01(Jul 13, 2012)
 * @version 0.01(Jul 13, 2012)
*/
package jp.regekatsu.language;


./jp/regekatsu/language/Text.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : ライブラリ
 * 業務名     : テキスト
 * 概要       : コアパッケージクラスにない文字列操作を行う
 */

package jp.regekatsu.language;

/**
 * Text クラスはコアパッケージクラスにない、文字列操作を実行するためのメソッドを含んでいます。
 *
 * @author DumBo
 * @since 0.01(Jul 12, 2012)
 * @version 0.01(Jul 12, 2012)
 */
public class Text {

	/**
	 * 指定された文字列が小数点を含んだ数値である場合にかぎり、true を返します。
	 *
	 * @param realNumber
	 *            指定された文字列
	 * @return 指定された文字列が小数点を含んだ数値の場合は true、そうでない場合は false
	 */
	public static boolean isRealNumber (String realNumber){
		try {
			Double.parseDouble(realNumber);
		} catch(NumberFormatException e) {
			return false;
		}
		return true;
	}

}


./jp/regekatsu/utility/Bmi.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : ライブラリ
 * 業務名     : ボディマス指数(BMI)
 * 概要       : ボディマス指数(BMI)の計算を行う
 */

package jp.regekatsu.utility;

import jp.regekatsu.utility.Sex;

/**
 * BMI クラスは、ボディマス指数(Body Mass Index)と呼ばれる、
 * 体重と身長の関係から算出される、ヒトの肥満度を表す体格指数の計算を行います。
 *
 * @author DumBo
 * @since 0.01(Apr 30, 2012)
 * @version 0.04(Jul 13, 2012)
 * @see jp.regekatsu.utility.Sex
 */
public class Bmi {

	/**
	 * BMI 値が 20.0 未満の時、「やせ」と判定された際に返される int 型定数です。
	 */
	public static final int JUDGE_SLENDER = 0;
	/**
	 * BMI 値が 20.0 以上 24.0 未満の時、「普通」と判定された際に返される int 型定数です。
	 */
	public static final int JUDGE_STANDARD = 1;
	/**
	 * BMI 値が 24.0 以上 26.4 未満の時、「過体重」と判定された際に返される int 型定数です。
	 */
	public static final int JUDGE_PLUMP = 2;
	/**
	 * BMI 値が 26.4 以上の時、「肥満」と判定された際に返される int 型定数です。
	 */
	public static final int JUDGE_FAT = 3;

	/** 男性において理想とされる BMI 指数を示す double 型定数です。 */
	private static final double IDEAL_BMI_MALE = 22.0d;
	/** 女性において理想とされる BMI 指数を示す double 型定数です。 */
	private static final double IDEAL_BMI_FEMALE = 21.0d;

	/** 性別 */
	private Sex sex;
	/** 身長 */
	private double height;
	/** 体重 */
	private double weight;
	/** 理想 BMI 指数 */
	private double idealBmi;

	/**
	 * 性別定数を男性に、身長(センチメートル)及び体重(キログラム)を
	 * 0.1 の double 型とした、BMI オブジェクトを作成します。
	 */
	public Bmi() {
		this(Sex.MALE, 0.1, 0.1);
	}

	/**
	 * 指定された性別定数と、身長(センチメートル)及び体重(キログラム)の double 値を使って、
	 * BMI オブジェクトを作成します。
	 *
	 * @param sex
	 *            指定された性別定数
	 * @param height
	 *            指定された身長(センチメートル)
	 * @param weight
	 *            指定された体重(キログラム)
	 */
	public Bmi(Sex sex, double height, double weight) {
		setSex(sex);
		setHeight(height);
		setWeight(weight);
	}

	/**
	 * 性別を、Sex 列挙定数で返します。
	 *
	 * @return 性別(Sex 列挙定数)
	 */
	public Sex getSex() {
		return sex;
	}

	/**
	 * 指定された性別定数を、Sex 列挙型で設定します。
	 *
	 * @param sex
	 *            指数された性別定数
	 * @throws IllegalArgumentException
	 *             性別定数以外の値が入ってしまった場合
	 */
	public void setSex(Sex sex) {

		this.sex = sex;

		// 性別によって理想 BMI を変更、設定する。
		switch (this.sex) {
		case MALE:
			idealBmi = IDEAL_BMI_MALE;
			break;
		case FEMALE:
			idealBmi = IDEAL_BMI_FEMALE;
			break;
		default:
			throw new IllegalArgumentException("予期しない例外が発生しました。");
		}

	}

	/**
	 * 身長をセンチメートル単位の double 型で返します。
	 *
	 * @return 指数された身長(センチメートル)
	 */
	public double getHeight() {
		return height;
	}

	/**
	 * 指定された身長を、センチメートル単位の double 型で設定します。
	 *
	 * @param height
	 *            指数された身長(センチメートル)
	 * @throws IllegalArgumentException
	 *             0.0 以下の値
	 */
	public void setHeight(double height) {
		// 身長の指定が 0.0 以下でないか確認する。
		if (height <= 0.0) {
			throw new IllegalArgumentException("身長は 0.0 以上を設定してください。");
		}
		this.height = height;
	}

	/**
	 * 体重をキログラム単位の double 型で返します。
	 *
	 * @return 指数された体重(キログラム)
	 */
	public double getWeight() {
		return weight;
	}

	/**
	 * 指定された体重を、キログラム単位の double 型で設定します。
	 *
	 * @param weight
	 *            指定された体重(キログラム)
	 * @throws IllegalArgumentException
	 *             0.0 以下の値
	 */
	public void setWeight(double weight) {
		// 体重の指定が 0.0 以下でないか確認する。
		if (weight <= 0.0) {
			throw new IllegalArgumentException("体重は 0.0 以上を設定してください。");
		}
		this.weight = weight;
	}

	/**
	 * BMI 指数から得られた判定結果を int 型定数で返します。
	 *
	 * @return BMI 指数から得られた判定結果を示す int 型定数
	 */
	public int getJudge() {

		double bmi = getBmi();

		int judge;

		// BMI 値が 20.0 未満なら、「やせ」と判定する。
		if (bmi < 20.0) {
			judge = JUDGE_SLENDER;

		// BMI 値が 20.0 以上 24.0 未満なら、「普通」と判定する。
		} else if (bmi >= 20.0 && bmi < 24.0) {
			judge = JUDGE_STANDARD;

		// BMI 値が 24.0 以上 26.4 未満なら、「過体重」と判定する。
		} else if (bmi >= 24.0 && bmi < 26.4) {
			judge = JUDGE_PLUMP;

		// BMI 値が 26.4 以上なら、「肥満」と判定する。
		} else {
			judge = JUDGE_FAT;

		}

		return judge;

	}

	/**
	 * BMI 指数を double 型で返します。
	 *
	 * @return BMI 指数
	 * @throws IllegalArgumentException
	 *             身長が 0.0 だった場合
	 */
	public double getBmi() {

		// もしも身長が 0.0 だった場合ゼロ除算となってしまう為、例外を発生させるようにする。
		if (height == 0.0) {
			throw new IllegalArgumentException("ゼロ除算が発生しました。"
					+ "設定を前もって行ったか確認してください。");
		}

		return weight / height / height * 10000.0;
	}

	/**
	 * 理想 BMI 指数を double 型で返します。
	 *
	 * @return 理想 BMI 指数
	 */
	public double getIdealBmi() {
		return idealBmi;
	}

	/**
	 * 理想 BMI 指数を double 型で設定します。
	 *
	 * @param idealBmi
	 *            理想 BMI 指数
	 */
	public void setIdealBmi(double idealBmi) {
		this.idealBmi = idealBmi;
	}

	/**
	 * 1 日に摂取するべきカロリーを double 型で返します。
	 *
	 * @return 1 日に摂取するべきカロリー
	 */
	public double getNecessaryCalory() {
		return getIdealWeight() * 30.0;
	}

	/**
	 * 理想体重をキロメートル単位の double 型で返します。
	 *
	 * @return 理想体重(キロメートル)
	 */
	public double getIdealWeight() {
		return height * height * idealBmi / 10000.0;
	}

}


./jp/regekatsu/utility/package-info.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : パッケージ
 * 業務名     : ユーティリティ
 * 概要       : パッケージの概要説明。
 */

/**
* Java プログラム言語の設計にあたり、コアパッケージに含まれない
* 実用的なクラスを提供します。
*
 * @author DumBo
 * @since 0.01(May 20, 2012)
 * @version 0.06(Jul 13, 2012)
 */
package jp.regekatsu.utility;


./jp/regekatsu/utility/Sex.java

/*
 * Copyright (c) 2012 DumBoさんの Homebrew 開発日記 All Right Reserved.
 *
 * システム名 : ライブラリ
 * 業務名     : 性別
 * 概要       : 性別を扱う
 */

package jp.regekatsu.utility;

/**
 * Sex 列挙型は性別を示す定数を含みます。
 *
 * @author DumBo
 * @since 0.01(Jul 13, 2012)
 * @version 0.01(Jul 13, 2012)
 */
public enum Sex {
	/** 男性であることを示します。*/
	MALE,
	/** 女性であることを示します。*/
	FEMALE;
}