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