最新GUIツールで基礎から学べる
連載:いまから始めるJava入門(3)

自分でクラスを作ってみよう

たけぞう
2001/1/22

 

 (1) サンプル:今回はカレンダー

   ウィザードで下準備

 新規プロジェクト・新規アプリケーションの作成方法は、もうあえて説明する必要はないでしょう。ウィザードを使って、それぞれ、次のようなファイルを作ってください。

新規プロジェクト
プロジェクトファイル java_study\Calendar.jpr
Applicationクラスの作成
パッケージ名 calendar
クラス名 CalendarApp
Frameクラスの作成
クラス名 CalndarFrame
タイトル カレンダー

(注:今回から、プロジェクトファイルを格納するディレクトリを"java_study"に統一することにしました。次回から、サンプルはすべてこのディレクトリに格納します)

 今回のサンプルは、特にメニューやステータスバーを使いませんが、もちろんお好みでつけてもらっても構いません。

    画面を2つに分割:年月表示エリアとカレンダー表示エリア

 最初に見てもらった図から分かるように、今回作るカレンダーは「年月表示エリア」と「カレンダー表示エリア」の2つの画面で構成されています。ですので、まずは2つの画面の土台を作ります。

 まず、前回と同様、以下の手順を踏みます。

1 プロジェクトペインで「CalendarFrame.java」を選択した後、[ファイルビュー]タブで[設計]を選択
2 UIデザイナーでウィンドウ全体をクリック
3 インスペクタの「layout」プロパティを「BorderLayout」に設定

 「BorderLayout」については前回説明しましたので、やはり説明は不要でしょう。前回の記事を参考にしてください。

 この次に、コンポーネントパレットで[Swing Containers]タブから「JPanel」、「JScrollPane」コンポーネントを選択し、それぞれ、North、Centerに張り付けます。前者が「年月表示エリア」、後者が「カレンダー表示エリア」の土台となるわけです。

 ここで、「カレンダー表示エリア」に「JScrollPane」を用いることに注意してください。JTableコンポーネントは、JscrollPane上で使うことを前提に作られており、それ以外のSwing Containerを用いても、うまく表示されません。

    年月表示エリアにコンポーネントを張り付ける

 次に、画面上部の年月表示エリアの「見た目」を作ります。まず、先ほど張り付けたJpanelコンポーネントの「layout」プロパティを「FlowLayout」に設定してください。
 「FlowLayout」とは、その上に張り付けられたコンポーネントを、張り付けられた順に均等に(流し込むように)横に並べていくレイアウト方式です。画面の幅に収まりきらないときは、2段目、3段目に並べます。

 この後、「JButton」、「JTextField」、「JLabel」コンポーネントを2つずつ、[Swing]タブから選択して、順に張り付けていってください(張り付けた後でも、設計画面上でコンポーネントをドラッグすることで、順番を並べ替えることができます)。

 プロパティの細かな設定については、第1回からお読みの皆さんならお分かりでしょうから、省略します。「Text」プロパティ以下、それぞれのプロパティを設定してください。

 ……おっと1つだけ。2つある「JTextField」コンポーネントのプロパティですが、

editable
false

に設定してください。こうすると、「JTextField」はユーザーが編集できなくなり、表示のみ可能となります。

(注:皆さんの中には機能を拡張して、年月をユーザーが直接書き込んで指定できるようにしたい方もいるでしょう。その場合は、このプロパティをtrueに設定し、テキストが編集されたときのイベントを処理するコードを書き加えてください)

 最後に、張り付けた各コンポーネントと、土台の「JPanel」コンポーネントのサイズを調整します。「minimumSize」「preparedSize」などのプロパティを編集してください。あわせて、その下の「JScrollPane」のサイズも調整してください。

    カレンダーの「モデル」クラスを作る

 続いて、いよいよカレンダー表示エリアの設定です。

 [Swing]タブから、「JTable」コンポーネントを選択し、ウィンドウ下部の、カレンダー表示エリアに張り付けます。

 さて、いつもならここでプロパティの設定に入るわけですが……今回は、その前にやることがあります。カレンダーの「モデル」クラスを作るのです。

 「モデル」クラスって何?と思われるかもしれませんが、能書きはとりあえずおいといて、ひとまず作る手順だけをたどっていきましょう(先にリクツを知りたい!という方はこちらを先にご覧ください)。

 「ファイル」メニューから、「新規クラス」を選択します。次のようなウィザード画面が現れます。

(画面をクリックすると拡大します)

 この画面で、次のように設定してください。

  • クラス名を「CalendarModel」にする
  • 「publicクラス」のチェックを外す
  • 親クラスに「javax.swing.table.AbstractTableModel」と設定する

 親クラスの設定については、入力画面右側の「…」の部分を押すと、次のようなツリー表示画面が現れますので、そこから選択してください。

 すると、「CalendarModel.java」が自動的に作られます。このファイルの中をのぞいてみましょう。

package calendar;
import javax.swing.table.*;

public class CalendarModel extends AbstractTableModel {
  

public CalendarModel() {
  }

  public int getColumnCount() {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
  }

  public Object getValueAt(int parm1, int parm2) {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
  }

  public int getRowCount() {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
 }
}

 このように、CalendarModelクラスを作るための「ひな型」がすでに出来上がっています。このひな型を埋める要領でCalendarModelクラスのコードを書いていきます。

 「//TODO: … 」というコメントの書かれたメソッドは、このクラスを完成させるのに必須のメソッドであることを意味しています。

 ……といっても、これらのメソッドが一体何のためのメソッドなのか、理解しないことには実装(コードを書いてプログラムを作ること)のしようがありませんね。その秘密は、「Java 2 プラットフォーム API 仕様」(JBuilderのヘルプか、サンのページから参照できます)をたどって、「TableModel」インターフェイス、「AbstractTableModel」クラスの解説を見ると分かります。

(注:もしJavaのプログラミングを極めたいなら、このリファレンスの使い方をぜひ会得して、使いこなしてください。ちょっとしたヒントが、ここにはたくさん隠されています)

 いま作っているCalendarModelクラスと、TableModelインターフェイス・AbstractTableModelクラスの関係が気になるかもしれません。いや、それ以前に「インターフェイスって何?」と思われるかもしれません。……が、このリクツもやはり後回しにしてしまいましょう。先ほどの「//TODO: …」と書かれたメソッドと、あと幾つかのメソッドを追加して、CalendarModelクラスを完成させます。

<ソース>
package calendar;


import java.util.*;

import javax.swing.table.*;



public class CalendarModel extends AbstractTableModel {


private Calendar calendar;
private int year;
private int month;


  private int getDate(int row, int col) {
    calendar.set(Calendar.YEAR, this.year); // 年の設定
    calendar.set(Calendar.MONTH, this.month); // 月の設定
    calendar.set(Calendar.WEEK_OF_MONTH, row + 1);
    calendar.set(Calendar.DAY_OF_WEEK, col + 1);
    return calendar.get(Calendar.DATE);
  }

  public CalendarModel() {
    calendar = Calendar.getInstance(); // 現在の日時に設定されたカレンダーを取得
    this.year = calendar.get(Calendar.YEAR); // 年の取得
    this.month = calendar.get(Calendar.MONTH); // 月の取得

  }

  public int getColumnCount() {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
    return 7;
  }


  public Object getValueAt(int parm1, int parm2) {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
  }


  public int getRowCount() {
    //TODO: この javax.swing.table.AbstractTableModel abstract メソッドを実装
    return 5;
  }


  /** 列名の設定 */
  public String getColumnName(int columnIndex) {
    String[] dayOfTheWeek = {
      "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    };
    return dayOfTheWeek[columnIndex];
  }


  public void addMonth(int delta) {
    month += delta;
    if (month > Calendar.DECEMBER) { // 次の年に繰り上げ
      year++;
      month -= 12;
    }
    else if (month < Calendar.JANUARY) { // 前の年に繰り下げ
      year--;
      month += 12;
    }
  }

  public int getYear() {
    return this.year;
  }

  public int getMonth() {
    /* 注;this.monthの値はそのまま月の値ではありません! */
    switch (this.month) {
      case Calendar.JANUARY: return 1;
      case Calendar.FEBRUARY: return 2;
      case Calendar.MARCH: return 3;
      case Calendar.APRIL: return 4;
      case Calendar.MAY: return 5;
      case Calendar.JUNE: return 6;
      case Calendar.JULY: return 7;
      case Calendar.AUGUST: return 8;
      case Calendar.SEPTEMBER: return 9;
      case Calendar.OCTOBER: return 10;
      case Calendar.NOVEMBER: return 11;
      case Calendar.DECEMBER: return 12;
      default: return 0;
    }
  }
}

 色が変わっている部分が、実際に手で書き加えた部分です。実際の日付計算には、Java2 APIにある「java.util.Calendar」というクラスを使っています。ぜひ、このクラスについても先ほどのリファレンスを引いて、仕様を調べてみてください。

    CalendarFrameにCalendarModelクラスのオブジェクト追加

 さてさて、こうしてできた「モデル」のCalendarModelクラスと、「JTable」コンポーネントを結び付けます。

1 プロジェクトペインで「CalendarFrame.java」を選択、[ファイルビュー]タブで[ソース]タブをクリックします。

  表示されたCalendarFrameクラスのソース内に、

TableModel calendarModel = new CalendarModel();

 という1行を加えてください(場所は、実際にソースを見て確認してください)。

2 [設計]タブ?をクリックし、プロパティ編集用のインスペクタを表示

  このインスペクタで

model
calendarModel

 と、「JTable」コンポーネントのプロパティを変更してください。

 実は1の記述は、普通のコンポーネントなら画面上に張り付ける際に、自動的にJBuilderが生成してくれていました。しかし、CalendarModelクラスは自前で作ったクラスですので、自分で書く必要があるというわけです。

(注:JBuilderで張り付けられるコンポーネントを自作することも可能です。が、ここでは触れないことにします)

    おまけのコードを追加・完成

 ここまでできれば、ほぼ出来上がりです……が、まだ完璧ではありません。幾つかコードをCalendarFrame.javaに追加して、最後の仕上げとなります。

 実際に、どこにどのようなコードを追加したのかは、サンプルのソースをじっくり眺めてみてください。あるいはご自分なりに工夫して、完成させてみてください。

(2)ここまでの種あかし


Index
第3回 自分でクラスを作ってみよう
(1) サンプル:今回はカレンダー
 ウィザードで下準備
 画面を2つに分割:年月表示エリアとカレンダー表示エリア
 年月表示エリアにコンポーネントを張り付ける
 「新規作成」メニューで編集エリアをクリアする
 カレンダーの「モデル」クラスを作る
 CalendarFrameにCalendarModelクラスのオブジェクトを追加する
 おまけのコードを追加・完成
  (2) ここまでの種明かし
 JTableとMVCモデル
 インターフェイスって何?
 

連載記事一覧




Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間