広告

■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
                      2010年02月03日

    Java総合講座 - 初心者から達人へのパスポート
                  2009年11月開講コース 012号

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:毎週日曜の夜に発行
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:毎週水曜の夜に発行
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(2009年11月開講コース)012号
 (当記事はvol.012のリバイバル(revival)版です。)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


========================================================
◆ 01.和暦を西暦に変換するクラス(続き)
========================================================

それでは、前回のソース・コードを解説しましょう。

なお小職の労力を節約するために、ソース・コードのコメントに
行番号などを指定するのは前回からやめておりますが、代わりに
Eclipseのエディターに行番号の表示機能(エディター画面の左端
に行番号が表示される)があります。

┌補足─────────────────────────┐
Eclipseのエディターに行番号が表示されていない場合は、次の
ように操作すれば行番号を表示できます。

(1)Eclipseを起動します。

(2)メニュー・バーから「ウインドウ」→「設定」を選択します。

(3)左側の「一般」の階層構造を開き(+マークをクリック)、
「エディター」の階層構造を開き(+マークをクリック)、
「テキスト・エディター」を選択(クリック)し、右側に表示さ
れる項目リストの中の「行番号の表示」にチェック・マークを入
れます(クリックすれば入る)。

(4)最後に「OK」ボタンをクリックします。
└───────────────────────────┘

以後、Eclipseに表示される行番号を見ながら解説を読んでください。

ただし、皆様が、小職とまったく同じ内容でEclipseに入力している
とは限りませんので、行番号がずれているときは皆様の側で合わせて
ください。

なお、Eclipseのエディターには適宜ソース・コードを折りたたむ機能
があり、ソース・コードが折りたたまれている箇所では行番号が飛んで
いるように見えます。
そのような場合は行の左端(行番号の右側)に折りたたみのマーク
(+のマーク)がありますので、それをクリックしてソース・コード
を広げておいてください。


では、最初にCalendarConverterクラスを見ていきましょう。

-------------------------------------------------------
package jp.co.flsi.lecture.util;

public class CalendarConverter {
   private int jaNameOfEra;  // 0 = 明治, 1 = 大正, 2 = 昭和, 3 = 平成
   private int jaYear;  // Japanese Calendar
   private int greYear;  // Gregorian Calendar
   private int Month;
   private int Day;
   public void setJaNameOfEra(int jaNameOfEra) {
      this.jaNameOfEra = jaNameOfEra;
   }
   public int getJaNameOfEra() {
      return jaNameOfEra;
   }
   public void setJaYear(int jaYear) {
      this.jaYear = jaYear;
   }
   public int getJaYear() {
      return jaYear;
   }
   public void setGreYear(int greYear) {
      this.greYear = greYear;
   }
   public int getGreYear() {
      return greYear;
   }
   public void setMonth(int month) {
      Month = month;
   }
   public int getMonth() {
      return Month;
   }
   public void setDay(int day) {
      Day = day;
   }
   public int getDay() {
      return Day;
   }
   public void convertJaCal2GreCal() {
      switch (getJaNameOfEra()) {
      case 0:
         setGreYear(getJaYear() + 1867);
         break;
      case 1:
         setGreYear(getJaYear() + 1911);
         break;
      case 2:
         setGreYear(getJaYear() + 1925);
         break;
      case 3:
         setGreYear(getJaYear() + 1988);
         break;
      default:
         setGreYear(0);
         break;
      }
   }
}
-------------------------------------------------------

4行目
-------------------------------------------------------
   private int jaNameOfEra;  // 0 = 明治, 1 = 大正, 2 = 昭和, 3 = 平成
-------------------------------------------------------
は、int型の変数jaNameOfEraを宣言していますが、これは和暦の年号
を表す変数として用意したものです。

現在生存している人の年齢を計算するために使用することを前提とし、
明治よりも以前の年号は除外しています。

jaNameOfEraの値が0のときは明治, 1のときは大正, 2のときは昭和,
3のときは平成を表すことにしています。

変数の値として、文字列ではなく数を使っていることに注意してくだ
さい。
一般的には、明治,大正,昭和,平成などの文字列そのものを変数に記憶
させるよりも、このように数で表現させたほうが効率がいいですし、
後の処理上、便利な場合が多いのです。
たとえば、今回の場合は後のswitch文で使用できます。
文字列ではswitch文は使用できません。


5行目から8行目まで
-------------------------------------------------------
   private int jaYear;  // Japanese Calendar
   private int greYear;  // Gregorian Calendar
   private int Month;
   private int Day;
-------------------------------------------------------
は年月日を表現する変数ですが、年に関してはjaYearとgreYearの2つ
の変数が宣言されています。

これは、西暦(Gregorian calendar)と和暦で年の値が異なるために
それぞれの変数を用意したものですが、逆に月や日については西暦と
和暦で同じものを使いますので、それぞれ変数は1つずつしか用意し
ていません。
(日本の一部の暦に併記されている「旧暦」では月や日についても
西暦とは違ってきますが、このクラスでは旧暦は扱わないことにし
ます。)

9行目から38行目まで
-------------------------------------------------------
   public void setJaNameOfEra(int jaNameOfEra) {
      this.jaNameOfEra = jaNameOfEra;
   }
   public int getJaNameOfEra() {
      return jaNameOfEra;
   }
   public void setJaYear(int jaYear) {
      this.jaYear = jaYear;
   }
   public int getJaYear() {
      return jaYear;
   }
   public void setGreYear(int greYear) {
      this.greYear = greYear;
   }
   public int getGreYear() {
      return greYear;
   }
   public void setMonth(int month) {
      Month = month;
   }
   public int getMonth() {
      return Month;
   }
   public void setDay(int day) {
      Day = day;
   }
   public int getDay() {
      return Day;
   }
-------------------------------------------------------

は、それぞれ4行目から8行目までに宣言した変数(属性)に対する
setメソッド、getメソッドです。


39行目から57行目まで

-------------------------------------------------------
   public void convertJaCal2GreCal() {
      switch (getJaNameOfEra()) {
      case 0:
         setGreYear(getJaYear() + 1867);
         break;
      case 1:
         setGreYear(getJaYear() + 1911);
         break;
      case 2:
         setGreYear(getJaYear() + 1925);
         break;
      case 3:
         setGreYear(getJaYear() + 1988);
         break;
      default:
         setGreYear(0);
         break;
      }
   }
-------------------------------------------------------

は、和暦から西暦に年を変換するためのメソッドです。月や日について
は変換する必要がないため何もしていません。

前回紹介したswitch文を使って、jaNameOfEraの値(そのgetメソッドで
あるgetJaNameOfEra()メソッドによって値を取り出している)に応じて
年の計算をしています。

たとえば、jaNameOfEraの値が0の場合は明治を意味しますから、jaYearの
値(getJaYear()メソッドで取り出している)に1867を足したもの(明治
元年は西暦1868年)を西暦の年としてgreYearに設定(setGreYear()メソッ
ドで設定)しています。

以下同様にしてjaNameOfEraの値が1の場合は大正、jaNameOfEraの値が2の
場合は昭和、jaNameOfEraの値が3の場合は平成として計算してgreYearに
設定しています。

それぞれの場合に計算の実行が終わって、次の行

break;

に進むと、このbreakという文は、それを囲んでいるブロック(ここでは
40行目のswitch文の右の{から56行目の}まで)から抜け出ることを
意味しますので、57行目に進み、57行目は何もすることはなくて、
たんにメソッドの終わりを表しているだけですから、メソッドの実行を
終了することになります。

なお、jaNameOfEraの値が0でも1でも2でも3でもない場合はdefault:のところ
のsetGreYear(0);が実行されることになりますが、これはjaNameOfEraの指定
が間違っている場合の設定値として年に0を設定することにしたものです。
これは、あくまでサンプルとして書いたコードで、この0の値を使って何かを
しようというつもりはありません。

でも、西暦0年の生まれの人なんて生存しているはずがありませんから、
0年という結果が出てきたら、すぐに誤りに気がつくでしょう。
このように、ありえない数値を返すことによって、誤りを知らせるやり方は
よく使われる手法の一つです。


和暦を西暦に変換するのは、比較的簡単だったのですが、逆に西暦を和暦に
変換するのは少し複雑で面倒になります。たとえば、明治は1868年9月8日から
始まる、というように和暦の年号は年の途中から変わる場合がほとんどだから、
月や日までチェックしてから変換しなければならないからです。
これは後で実際にプログラミングしてみましょう。


では、次にCalendarConverterWindowクラスのほうを見てみましょう。


-------------------------------------------------------
package jp.co.flsi.lecture.ui;

import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import jp.co.flsi.lecture.util.CalendarConverter;

public class CalendarConverterWindow extends Frame {
   private CalendarEventListener eventListener = new CalendarEventListener();
   private CalendarActionListener actionListener = new CalendarActionListener();
   private Label labelJaCalendar = new Label();
   private Panel ckboxPanel = new Panel();
   private CheckboxGroup nameOfEraCkboxGroup = new CheckboxGroup();
   private Checkbox checkboxMeiji = new Checkbox("明治", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxTaisho = new Checkbox("大正", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxShowa = new Checkbox("昭和", getNameOfEraCkboxGroup(), true);
   private Checkbox checkboxHeisei = new Checkbox("平成", getNameOfEraCkboxGroup(), false);
   private Label labelJaYear = new Label();
   private Label labelJaMonth = new Label();
   private Label labelJaDay = new Label();
   private Label labelGreCalendar = new Label();
   private Label labelGreYear = new Label();
   private Label labelGreMonth = new Label();
   private Label labelGreDay = new Label();
   private Button convertJa2GreButton = new Button();
   private TextField textFieldJaYear = new TextField();
   private TextField textFieldJaMonth = new TextField();
   private TextField textFieldJaDay = new TextField();
   private TextField textFieldGreYear = new TextField();
   private TextField textFieldGreMonth = new TextField();
   private TextField textFieldGreDay = new TextField();
  
   class CalendarEventListener implements WindowListener {
      public void windowActivated(WindowEvent e) {};
      public void windowClosed(WindowEvent e) {
         System.exit(0);
      };
      public void windowClosing(WindowEvent e) {
         Frame frame = (Frame)e.getSource();
         frame.setVisible(false);
         frame.dispose();
      };
      public void windowDeactivated(WindowEvent e) {};
      public void windowDeiconified(WindowEvent e) {};
      public void windowIconified(WindowEvent e) {};
      public void windowOpened(WindowEvent e) {};
   };
  
   class CalendarActionListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         Button button = (Button)e.getSource();
         CalendarConverterWindow window = (CalendarConverterWindow)button.getParent();
         CalendarConverter calendarConverter = new CalendarConverter();
         if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("明治")) calendarConverter.setJaNameOfEra(0);
         else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("大正")) calendarConverter.setJaNameOfEra(1);
         else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("昭和")) calendarConverter.setJaNameOfEra(2);
         else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("平成")) calendarConverter.setJaNameOfEra(3);
         calendarConverter.setJaYear(Integer.parseInt(window.getTextFieldJaYear().getText()));
         calendarConverter.setMonth(Integer.parseInt(window.getTextFieldJaMonth().getText()));
         calendarConverter.setDay(Integer.parseInt(window.getTextFieldJaDay().getText()));
         calendarConverter.convertJaCal2GreCal();
         window.getTextFieldGreYear().setText(Integer.toString(calendarConverter.getGreYear()));
         window.getTextFieldGreMonth().setText(Integer.toString(calendarConverter.getMonth()));
         window.getTextFieldGreDay().setText(Integer.toString(calendarConverter.getDay()));
      };
   };
  
   public CalendarConverterWindow()  {
      super();
      setTitle("和暦西暦変換");
      setSize(400, 150);
      setLayout(null);
      labelJaCalendar.setBounds(10, 30, 200, 20);
      ckboxPanel.setLayout(new GridLayout(1,4));
      ckboxPanel.add(checkboxMeiji);
      ckboxPanel.add(checkboxTaisho);
      ckboxPanel.add(checkboxShowa);
      ckboxPanel.add(checkboxHeisei);
      ckboxPanel.setBounds(45, 60, 180, 20);
      getTextFieldJaYear().setBounds(230, 60, 20, 20);
      labelJaYear.setBounds(255, 60, 20, 20);
      getTextFieldJaMonth().setBounds(290, 60, 20, 20);
      labelJaMonth.setBounds(315, 60, 20, 20);
      getTextFieldJaDay().setBounds(350, 60, 20, 20);
      labelJaDay.setBounds(375, 60, 20, 20);
      convertJa2GreButton.setBounds(120,90, 160, 20);
      labelGreCalendar.setBounds(10, 120, 200, 20);
      getTextFieldGreYear().setBounds(210, 120, 40, 20);
      labelGreYear.setBounds(255, 120, 20, 20);
      getTextFieldGreMonth().setBounds(290, 120, 20, 20);
      labelGreMonth.setBounds(315, 120, 20, 20);
      getTextFieldGreDay().setBounds(350, 120, 20, 20);
      labelGreDay.setBounds(375, 120, 20, 20);
      add(labelJaCalendar);
      add(ckboxPanel);
      add(getTextFieldJaYear());
      add(labelJaYear);
      add(getTextFieldJaMonth());
      add(labelJaMonth);
      add(getTextFieldJaDay());
      add(labelJaDay);
      add(convertJa2GreButton);
      add(labelGreCalendar);
      add(getTextFieldGreYear());
      add(labelGreYear);
      add(getTextFieldGreMonth());
      add(labelGreMonth);
      add(getTextFieldGreDay());
      add(labelGreDay);
      labelJaCalendar.setText("和暦:");
      labelJaYear.setText("年");
      labelJaMonth.setText("月");
      labelJaDay.setText("日");
      convertJa2GreButton.setLabel("和暦から西暦へ変換");
      labelGreCalendar.setText("西暦:");
      labelGreYear.setText("年");
      labelGreMonth.setText("月");
      labelGreDay.setText("日");
      convertJa2GreButton.addActionListener(actionListener);
      addWindowListener(eventListener);
      setVisible(true);
   }

   public CheckboxGroup getNameOfEraCkboxGroup() {
      return nameOfEraCkboxGroup;
   }

   public TextField getTextFieldJaYear() {
      return textFieldJaYear;
   }

   public TextField getTextFieldJaMonth() {
      return textFieldJaMonth;
   }

   public TextField getTextFieldJaDay() {
      return textFieldJaDay;
   }

   public TextField getTextFieldGreYear() {
      return textFieldGreYear;
   }

   public TextField getTextFieldGreMonth() {
      return textFieldGreMonth;
   }

   public TextField getTextFieldGreDay() {
      return textFieldGreDay;
   }


   public static void main(String[] args) {
      CalendarConverterWindow frame = new CalendarConverterWindow();
   }

}
-------------------------------------------------------


何度も何度も同じようなものを説明しているとうんざりしてくるでしょうから、
これまでに説明した内容と同様の箇所は極力説明を省くことにします。


では、今回新しく出てきたGUI部品について説明しましょう。

22行目から27行目

-------------------------------------------------------
   private Panel ckboxPanel = new Panel();
   private CheckboxGroup nameOfEraCkboxGroup = new CheckboxGroup();
   private Checkbox checkboxMeiji = new Checkbox("明治", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxTaisho = new Checkbox("大正", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxShowa = new Checkbox("昭和", getNameOfEraCkboxGroup(), true);
   private Checkbox checkboxHeisei = new Checkbox("平成", getNameOfEraCkboxGroup(), false);
-------------------------------------------------------

を見てください。

22行目のPanelというのは、GUI部品を貼り付ける画板のようなGUI部品で、以前
一寸紹介したContainer(GUI部品の入れ物)の一種です。
明治、大正、昭和、平成をラジオ・ボタン(一つのグループに属する複数のボタン
があり、そのうち同時に一つのボタンしか押せないような形式のボタン)の形式で
選択できるようにするために、複数のボタンを並べて置くための土台として利用し
ます。

23行目
-------------------------------------------------------
  private CheckboxGroup nameOfEraCkboxGroup = new CheckboxGroup();
-------------------------------------------------------
のCheckboxGroupというのはラジオ・ボタンの一つのグループを表現するクラスです。

ここでは、年号(the name of an era)を表現するラジオ・ボタン(AWTではCheckbox)
のグループであることから、theNameOfAnEraCheckboxGroupを略してnameOfEraCkboxGroupという変数名にしています。

24行目から27行目
-------------------------------------------------------
   private Checkbox checkboxMeiji = new Checkbox("明治", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxTaisho = new Checkbox("大正", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxShowa = new Checkbox("昭和", getNameOfEraCkboxGroup(), true);
   private Checkbox checkboxHeisei = new Checkbox("平成", getNameOfEraCkboxGroup(), false);
-------------------------------------------------------
のCheckboxはラジオ・ボタンを表すクラスです。
単独ではチェック・ボックス(チェックを入れたりはずしたりするGUI部品)と
しても使用できるため、Checkboxという名前になっています。

ちょっとわかりにくいですが、とにかくラジオ・ボタンにはCheckboxを使う
ということを覚えておいてください。

コンストラクターCheckbox()の2番目の引数にgetNameOfEraCkboxGroup()とある
のはラジオ・ボタンのグループを指定しているものです。

ここでは、後で定義しているgetNameOfEraCkboxGroup()というnameOfEraCkboxGroup
のgetメソッドを使って指定していますが、ここに直接nameOfEraCkboxGroupを指定
しても同じことです。
しかし、getメソッドが用意されているときはgetメソッドを使うのが原則です。

このように指定しておくと、これらのCheckboxのインスタンスはnameOfEraCkboxGroup
というグループに属することになります。

3番目の引数のfalseとかtrueとかいうのはこのラジオ・ボタンが選択されている
状態かどうかを指定するもので、falseは選択されていないことを、trueは選択さ
れていることを意味します。
(同じグループに属するラジオ・ボタンは同時に一つだけしか選択状態にできない
ことにご注意ください。)
ただし、ここでの指定はあくまで初期状態を指定するもので、その後、ウインドウ
上で別のラジオ・ボタンを選択すれば、選択状態は変化します。


次に63行目から74行目

-------------------------------------------------------
   CalendarConverter calendarConverter = new CalendarConverter();
   if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("明治")) calendarConverter.setJaNameOfEra(0);
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("大正")) calendarConverter.setJaNameOfEra(1);
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("昭和")) calendarConverter.setJaNameOfEra(2);
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("平成")) calendarConverter.setJaNameOfEra(3);
   calendarConverter.setJaYear(Integer.parseInt(window.getTextFieldJaYear().getText()));
   calendarConverter.setMonth(Integer.parseInt(window.getTextFieldJaMonth().getText()));
   calendarConverter.setDay(Integer.parseInt(window.getTextFieldJaDay().getText()));
   calendarConverter.convertJaCal2GreCal();
   window.getTextFieldGreYear().setText(Integer.toString(calendarConverter.getGreYear()));
   window.getTextFieldGreMonth().setText(Integer.toString(calendarConverter.getMonth()));
   window.getTextFieldGreDay().setText(Integer.toString(calendarConverter.getDay()));
-------------------------------------------------------

を見てみましょう。

これらはCalendarActionListenerというアクション・リスナー(ActionListener)
の中で定義されていますが、これらの文がウインドウ上のボタンをクリックしたとき
に実行されることは、ソース・コードをずうっと読んでいくとわかりますね
(以前HumanWindowの説明をしたときと同じ仕組みです)。

まず63行目ではCalendarConverterのインスタンスcalendarConverterを生成して
います。

64行目
-------------------------------------------------------
   if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("明治")) calendarConverter.setJaNameOfEra(0);
-------------------------------------------------------
では、window.getNameOfEraCkboxGroup()によって、このウインドウ
(CalendarConverterWindow)のnameOfEraCkboxGroupオブジェクトを取り出し
(getNameOfEraCkboxGroup()はnameOfEraCkboxGroupを取り出すためのgetメソッ
ドで、134行目から136行目に定義されている)ていますが、このオブジェ
クト(CheckboxGroupクラス)のgetSelectedCheckbox()を呼び出すとそのグルー
プ内で現在選択されているラジオ・ボタンを教えてくれます。

さらに、そのラジオ・ボタン(Checkbox)のgetLabel()メソッドを呼び出すと、
そのラジオ・ボタンに書かれているラベル(画面上に表示される文字列)を教え
てくれます。

このgetLabel()メソッドが返す戻り値(文字列)はString型です。
Stringクラスのequals()メソッドは引数に指定した文字列と等しいかどうかを
答えてくれますので、equals("明治")というメソッド呼び出しだと、その選択
されているラジオ・ボタンのラベルが明治の場合には真(true)が返って来ま
す。

そうすると、このif文の右側のcalendarConverter.setJaNameOfEra(0);が実行
され、calendarConverterオブジェクトのjaNameOfEraという属性に0という値が
設定されることになります。
setJaNameOfEra()はjaNameOfEraのsetメソッドで、0という値は明治を表すこと
にしているのでしたね。

同様に65行目から67行目
-------------------------------------------------------
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("大正")) calendarConverter.setJaNameOfEra(1);
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("昭和")) calendarConverter.setJaNameOfEra(2);
   else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("平成")) calendarConverter.setJaNameOfEra(3);
-------------------------------------------------------
で、それぞれ大正、昭和、平成のラジオ・ボタンが選択された場合に、それぞれ
1、2、3という値がcalendarConverterオブジェクトのjaNameOfEraに設定される
ようになっています。

68行目から70行目
-------------------------------------------------------
   calendarConverter.setJaYear(Integer.parseInt(window.getTextFieldJaYear().getText()));
   calendarConverter.setMonth(Integer.parseInt(window.getTextFieldJaMonth().getText()));
   calendarConverter.setDay(Integer.parseInt(window.getTextFieldJaDay().getText()));
-------------------------------------------------------
は、それぞれウインドウのテキスト・フィールド(TextField)に入力されたデータ
を取り出して、それぞれcalendarConverterオブジェクトのjaYear、month、day属性
に設定しています。
IntegerのparseInt()メソッドやTextFieldのgetText()メソッドなどについて忘れ
てしまった人はHumanWindowのときの説明を見てください。

71行目
-------------------------------------------------------
   calendarConverter.convertJaCal2GreCal();
-------------------------------------------------------
でcalendarConverterにconvertJaCal2GreCal()メソッドを実行させています。

これで以上のデータを和暦から西暦へと変換してくれます。

72行目
-------------------------------------------------------
   window.getTextFieldGreYear().setText(Integer.toString(calendarConverter.getGreYear()));
-------------------------------------------------------
のsetText()はTextFieldクラスのメソッドで、引数に指定した文字列をテキスト・
フィールドに書き込むものです。

その引数にInteger.toString(calendarConverter.getGreYear())というのが指定
されていますが、IntegerのtoString()はちょうどparseInt()の逆の仕事をする
もので、引数に指定された数を文字列に変換してくれるメソッドです。

これによってcalendarConverter.getGreYear()の戻り値、すなわちcalendarConverter
のgreYear属性の値が文字列に変換されてテキスト・フィールドに表示されることに
なります。

73行目から74行目
-------------------------------------------------------
   window.getTextFieldGreMonth().setText(Integer.toString(calendarConverter.getMonth()));
   window.getTextFieldGreDay().setText(Integer.toString(calendarConverter.getDay()));
-------------------------------------------------------
も同様にして、それぞれmonth、dayの属性をテキスト・フィールドに表示します。


CalendarConverterWindowのコンストラクターの定義の中を見てみましょう。

84行目
-------------------------------------------------------
      ckboxPanel.setLayout(new GridLayout(1,4));
-------------------------------------------------------
は、ckboxPanelの中にレイアウト・マネージャーとしてGridLayoutを指定している
ものです。

GridLayoutは格子(Grid)上にGUI部品を並べるレイアウト・マネージャーで、
new GridLayout(1,4)のように引数2個を指定したコンストラクターを呼び出して
インスタンス生成すると、1行4列の格子上にGUI部品を並べられます。
つまり、一つ目の引数が行の数、二つ目の引数が列の数を表します。

85行目から88行目
-------------------------------------------------------
      ckboxPanel.add(checkboxMeiji);
      ckboxPanel.add(checkboxTaisho);
      ckboxPanel.add(checkboxShowa);
      ckboxPanel.add(checkboxHeisei);
-------------------------------------------------------
はckboxPanelにそれぞれのラジオ・ボタンを貼り付け(追加)しています。
1行4列の格子が用意されていますから、この場合は格子上の左から順番にラジオ・
ボタンが張り付いていきます。


残りのコードは、もう自力で理解できることと思います。
もし、わからない所がありましたら、下のほうに書かれているホームページにて
質問をお寄せください。



では、次に西暦を和暦に変換するメソッドを作ってみましょう。
下記がその例です。

-------------------------------------------------------
public void convertGreCal2JaCal() {
   if (1989 < getGreYear() || 1989 == getGreYear() && ((1 == getMonth() && 8 <= getDay()) || 1 < getMonth())) {
      setJaNameOfEra(3);
      setJaYear(getGreYear() - 1988);
   }
   else if (1926 < getGreYear() || 1926 == getGreYear() && ((12 == getMonth() && 25 <= getDay()))) {
      setJaNameOfEra(2);
      setJaYear(getGreYear() - 1925);
   }
   else if (1912 < getGreYear() || 1912 == getGreYear() && ((7 == getMonth() && 30 <= getDay()) || 7 < getMonth())) {
      setJaNameOfEra(1);
      setJaYear(getGreYear() - 1911);
   }
   else if (1868 < getGreYear() || 1868 == getGreYear() && ((9 == getMonth() && 8 <= getDay()) || 9 < getMonth())) {
      setJaNameOfEra(0);
      setJaYear(getGreYear() - 1867);
   }
}
-------------------------------------------------------

平成は1989年1月8日から始まっていますから、
-------------------------------------------------------
   if (1989 < getGreYear() || 1989 == getGreYear() && ((1 == getMonth() && 8 <= getDay()) || 1 < getMonth())) {
      setJaNameOfEra(3);
      setJaYear(getGreYear() - 1988);
   }
-------------------------------------------------------
というように指定して、greYearの値が1989より大きい(1990年以降)であるか、
あるいはまたは1989年(1989 == getGreYear())でかつ「1月でかつ8日以後
(1 == getMonth() && 8 <= getDay())であるか、または2月以降(1 < getMonth())」
であれば平成であると判断し、jaNameOfEraに3を設定(setJaNameOfEra(3))し、
西暦の年から1988を引いたものを和暦の年とします。

ここで、&&は「かつ」を意味する論理演算子で、||は「または」を意味する
論理演算子です。

同様にして
-------------------------------------------------------
   else if (1926 < getGreYear() || 1926 == getGreYear() && ((12 == getMonth() && 25 <= getDay()))) {
      setJaNameOfEra(2);
      setJaYear(getGreYear() - 1925);
   }
   else if (1912 < getGreYear() || 1912 == getGreYear() && ((7 == getMonth() && 30 <= getDay()) || 7 < getMonth())) {
      setJaNameOfEra(1);
      setJaYear(getGreYear() - 1911);
   }
   else if (1868 < getGreYear() || 1868 == getGreYear() && ((9 == getMonth() && 8 <= getDay()) || 9 < getMonth())) {
      setJaNameOfEra(0);
      setJaYear(getGreYear() - 1867);
   }
-------------------------------------------------------
は、他の年月日の場合についても和暦の年号を判定し、設定を行っています。

それぞれ、平成に判定された年月日よりも前で1926年12月25日以降なら昭和、
昭和に判定された年月日よりも前で1912年7月30日以降なら大正、大正に判定さ
れた年月日よりも前で1868年9月8日以降なら明治という条件で判定しています。


このconvertGreCal2JaCal()のメソッド定義をCalendarConverterクラスの
convertJaCal2GreCal()メソッドの定義の下に追加しましょう。


次に、このconvertGreCal2JaCal()メソッドを呼び出して西暦から和暦に変換作業を
行えるように、CalendarConverterWindowクラスを改良してみましょう。

以下が改良を行ったCalendarConverterWindowクラスの例です。


-------------------------------------------------------
package jp.co.flsi.lecture.ui;

import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import jp.co.flsi.lecture.util.CalendarConverter;

public class CalendarConverterWindow extends Frame {
   private CalendarEventListener eventListener = new CalendarEventListener();
   private CalendarActionListener actionListener = new CalendarActionListener();
   private Label labelJaCalendar = new Label();
   private Panel ckboxPanel = new Panel();
   private CheckboxGroup nameOfEraCkboxGroup = new CheckboxGroup();
   private Checkbox checkboxMeiji = new Checkbox("明治", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxTaisho = new Checkbox("大正", getNameOfEraCkboxGroup(), false);
   private Checkbox checkboxShowa = new Checkbox("昭和", getNameOfEraCkboxGroup(), true);
   private Checkbox checkboxHeisei = new Checkbox("平成", getNameOfEraCkboxGroup(), false);
   private Label labelJaYear = new Label();
   private Label labelJaMonth = new Label();
   private Label labelJaDay = new Label();
   private Label labelGreCalendar = new Label();
   private Label labelGreYear = new Label();
   private Label labelGreMonth = new Label();
   private Label labelGreDay = new Label();
   private Button convertJa2GreButton = new Button();
   private Button convertGre2JaButton = new Button();
   private TextField textFieldJaYear = new TextField();
   private TextField textFieldJaMonth = new TextField();
   private TextField textFieldJaDay = new TextField();
   private TextField textFieldGreYear = new TextField();
   private TextField textFieldGreMonth = new TextField();
   private TextField textFieldGreDay = new TextField();
  
   class CalendarEventListener implements WindowListener {
      public void windowActivated(WindowEvent e) {};
      public void windowClosed(WindowEvent e) {
         System.exit(0);
      };
      public void windowClosing(WindowEvent e) {
         Frame frame = (Frame)e.getSource();
         frame.setVisible(false);
         frame.dispose();
      };
      public void windowDeactivated(WindowEvent e) {};
      public void windowDeiconified(WindowEvent e) {};
      public void windowIconified(WindowEvent e) {};
      public void windowOpened(WindowEvent e) {};
   };
  
   class CalendarActionListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         Button button = (Button)e.getSource();
         CalendarConverterWindow window = (CalendarConverterWindow)button.getParent();
         CalendarConverter calendarConverter = new CalendarConverter();
         if (button.getLabel().equals("和暦から西暦へ変換")){
            if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("明治")) calendarConverter.setJaNameOfEra(0);
            else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("大正")) calendarConverter.setJaNameOfEra(1);
            else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("昭和")) calendarConverter.setJaNameOfEra(2);
            else if (window.getNameOfEraCkboxGroup().getSelectedCheckbox().getLabel().equals("平成")) calendarConverter.setJaNameOfEra(3);
            calendarConverter.setJaYear(Integer.parseInt(window.getTextFieldJaYear().getText()));
            calendarConverter.setMonth(Integer.parseInt(window.getTextFieldJaMonth().getText()));
            calendarConverter.setDay(Integer.parseInt(window.getTextFieldJaDay().getText()));
            calendarConverter.convertJaCal2GreCal();
            window.getTextFieldGreYear().setText(Integer.toString(calendarConverter.getGreYear()));
            window.getTextFieldGreMonth().setText(Integer.toString(calendarConverter.getMonth()));
            window.getTextFieldGreDay().setText(Integer.toString(calendarConverter.getDay()));
         }
         else {
            calendarConverter.setGreYear(Integer.parseInt(window.getTextFieldGreYear().getText()));
            calendarConverter.setMonth(Integer.parseInt(window.getTextFieldGreMonth().getText()));
            calendarConverter.setDay(Integer.parseInt(window.getTextFieldGreDay().getText()));
            calendarConverter.convertGreCal2JaCal();
            if (calendarConverter.getJaNameOfEra() == 0) window.getNameOfEraCkboxGroup().setSelectedCheckbox(window.checkboxMeiji) ;
            else if (calendarConverter.getJaNameOfEra() == 1) window.getNameOfEraCkboxGroup().setSelectedCheckbox(window.checkboxTaisho) ;
            else if (calendarConverter.getJaNameOfEra() == 2) window.getNameOfEraCkboxGroup().setSelectedCheckbox(window.checkboxShowa) ;
            else if (calendarConverter.getJaNameOfEra() == 3) window.getNameOfEraCkboxGroup().setSelectedCheckbox(window.checkboxHeisei) ;
            window.getTextFieldJaYear().setText(Integer.toString(calendarConverter.getJaYear()));
            window.getTextFieldJaMonth().setText(Integer.toString(calendarConverter.getMonth()));
            window.getTextFieldJaDay().setText(Integer.toString(calendarConverter.getDay()));
         }
      };
   };
  
   public CalendarConverterWindow()  {
      super();
      setTitle("和暦西暦変換");
      setSize(400, 150);
      setLayout(null);
      labelJaCalendar.setBounds(10, 30, 200, 20);
      ckboxPanel.setLayout(new GridLayout(1,4));
      ckboxPanel.add(checkboxMeiji);
      ckboxPanel.add(checkboxTaisho);
      ckboxPanel.add(checkboxShowa);
      ckboxPanel.add(checkboxHeisei);
      ckboxPanel.setBounds(45, 60, 180, 20);
      getTextFieldJaYear().setBounds(230, 60, 20, 20);
      labelJaYear.setBounds(255, 60, 20, 20);
      getTextFieldJaMonth().setBounds(290, 60, 20, 20);
      labelJaMonth.setBounds(315, 60, 20, 20);
      getTextFieldJaDay().setBounds(350, 60, 20, 20);
      labelJaDay.setBounds(375, 60, 20, 20);
      convertJa2GreButton.setBounds(220,90, 160, 20);
      convertGre2JaButton.setBounds(20,90, 160, 20);
      labelGreCalendar.setBounds(10, 120, 200, 20);
      getTextFieldGreYear().setBounds(210, 120, 40, 20);
      labelGreYear.setBounds(255, 120, 20, 20);
      getTextFieldGreMonth().setBounds(290, 120, 20, 20);
      labelGreMonth.setBounds(315, 120, 20, 20);
      getTextFieldGreDay().setBounds(350, 120, 20, 20);
      labelGreDay.setBounds(375, 120, 20, 20);
      add(labelJaCalendar);
      add(ckboxPanel);
      add(getTextFieldJaYear());
      add(labelJaYear);
      add(getTextFieldJaMonth());
      add(labelJaMonth);
      add(getTextFieldJaDay());
      add(labelJaDay);
      add(convertJa2GreButton);
      add(convertGre2JaButton);
      add(labelGreCalendar);
      add(getTextFieldGreYear());
      add(labelGreYear);
      add(getTextFieldGreMonth());
      add(labelGreMonth);
      add(getTextFieldGreDay());
      add(labelGreDay);
      labelJaCalendar.setText("和暦:");
      labelJaYear.setText("年");
      labelJaMonth.setText("月");
      labelJaDay.setText("日");
      convertJa2GreButton.setLabel("和暦から西暦へ変換");
      convertGre2JaButton.setLabel("西暦から和暦へ変換");
      labelGreCalendar.setText("西暦:");
      labelGreYear.setText("年");
      labelGreMonth.setText("月");
      labelGreDay.setText("日");
      convertJa2GreButton.addActionListener(actionListener);
      convertGre2JaButton.addActionListener(actionListener);
      addWindowListener(eventListener);
      setVisible(true);
   }

   public CheckboxGroup getNameOfEraCkboxGroup() {
      return nameOfEraCkboxGroup;
   }

   public TextField getTextFieldJaYear() {
      return textFieldJaYear;
   }

   public TextField getTextFieldJaMonth() {
      return textFieldJaMonth;
   }

   public TextField getTextFieldJaDay() {
      return textFieldJaDay;
   }

   public TextField getTextFieldGreYear() {
      return textFieldGreYear;
   }

   public TextField getTextFieldGreMonth() {
      return textFieldGreMonth;
   }

   public TextField getTextFieldGreDay() {
      return textFieldGreDay;
   }

   public static void main(String[] args) {
      CalendarConverterWindow frame = new CalendarConverterWindow();
   }

}
-------------------------------------------------------


どのような改良を行ったのかは、次回説明します。


これらの改良をEclipseで入力して保管し、実行してテストしてみてください
(西暦側に年月日を入力し、「西暦から和暦へ変換」ボタンをクリックします)。


今回は、ここまでとします。



================================================
◆ 02.演習問題
================================================

上記の改良されたCalendarConverterWindowクラスにおいて、何がどのように変わっ
たのか説明しなさい。



======================================================
◆ 03.前回の演習問題の答
======================================================

今回の本文中に解答が含まれています。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2010 Future Lifestyle Inc. 不許無断複製