アトリエ・エクレア

2DCG&3DCG, プログラミング, 日記などを掲載してます。

Java言語

Java言語

<免責事項> この記事は、管理人の個人的な覚書きのためのものです。内容に間違いがあっても責任は負いません。

  • Java API → Link

Java言語

プログラミング言語JavaおよびJavaプラットフォームは、1990年代前半にサン・マイクロシステムズジェームズ・ゴスリンなどによって開発された(1995年登場)。
※ サン・マイクロシステムズ(2010年1月27日にオラクルにより吸収合併される

表記は Jのみが大文字の「Java」が正しい。「JAVA」は正式な表記ではない。
※「Java」の名称の由来ははっきりしていないらしい。

< Javaの主な特徴 >

  • プラットフォームに依存しないアプリケーションソフトウェアの開発と配備を行うことができる。
  • 開発されたソフトウェアは、Java仮想マシンの下で動作する。
  • オブジェクト指向プログラミングの考え方に基づいて設計された言語であり、ソフトウェアの開発と保守の複雑さを低減し、開発効率と保守性を高める。
  • 構文は C および C++ から多くを引き継いでいる。

ソースファイルの拡張子

sample.java のように、「 .java 」を使う。

出力

public class Sample {

    // mainメソッド
    public static void main(String[] args) {
        // リテラル
        System.out.println(523);              // 数値リテラル (整数リテラル)
        System.out.println(3.14159);          // 数値リテラル (浮動小数点数リテラル)
        System.out.println('A');              // 文字リテラル
        System.out.println("Hello, world!"); // 文字列リテラル

        // 数値リテラルの表記
        System.out.println("10進数の15は、10進数表記では" + 15);   // 10進数 (結果: 15)
        System.out.println("8進数の15は、10進数表記では" + 015);   // 8進数  (結果: 13)
        System.out.println("16進数の15は、10進数表記では" + 0x15); // 16進数 (結果: 21)

        // 文字コード
        System.out.println("Unicode 10進数の65は、" + (char) 65);  // 結果: A
        System.out.println("Unicode 8進数101は、\101");            // 結果: A
        System.out.println("Unicode 16進数の41は、\u0041");        // 結果: A

        // エスケープシーケンス
        System.out.println("\\100");          // 結果: \100
        System.out.print(753 + "\n");         // 結果: 753改行   ※ System.out.print()は、デフォルトで改行がない。
        System.out.println("152\t35\t672");   // 結果: 152 35 672

        // 改行のみ
        System.out.println();                 // 結果: (改行)
    }

}

入力

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
// import java.io.*; ←上の三行の代わりに、この書き方も可能。しかし、細かく指定するほうが間違いは少ない。

public class Sample {

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		System.out.println("円の半径を入力してください。");
		String str1 = br.readLine();
		int radius = Integer.parseInt(str1);

		System.out.println("円周率を入力してください。");
		String str2 = br.readLine();
		double pi = Double.parseDouble(str2);

		double area = radius * radius * pi;

		System.out.println("半径" + radius + "cmの円の面積は、" + area + "cm^2 です。");
	}

}

コメント

/* 範囲コメント */

/* 複数行の
コメント */

// 一行コメント(改行まで)

< ドキュメンテーションコメント >

  • 主にクラスの概要やメソッドの概要を記述しておき、EclipseでJavadocからHTML形式のドキュメントファイルを生成することができる。
  • 右クリック → ソース → 要素コメントの生成 でコメントを記述。
  • プロパティー → リソース → テキスト・ファイルのエンコード → UTF-8 。
  • プロジェクト → Javadocの生成
  • 文書タイトル入力
  • VMオプション → -encoding UTF-8 -charset UTF-8
  • ナビゲート → 添付されたJavadocを開く
/**
 * Sampleクラスは、mainメソッドを含みます
 * @author 名前
 */
public class Sample {

	public static void main(String[] args) {

	}

}

※本稿のサンプルプログラムは正式な開発ではなく、只の覚書き説明なので、クラスの概要やメソッドの概要は一行コメント(//)で済ます。
正式な開発ではドキュメンテーションコメントを記述するのが良い。

特殊文字 (エスケープシーケンスの利用)

特殊文字の例 (※他にもある。)
文字 意味
¥b バックスペース
¥f フォームフィード: 改ページ
¥n 改行
¥r キャリッジリターン: 行頭へ復帰
¥t 水平タブ
¥¥ 円記号 ( ¥ )
¥' 単一引用符: シングルクォーテーション ( ' )
¥'' 二重引用符: ダブルクォーテーション ( " )
¥ooo 8進数oooの文字コード ( 円記号と、1~ 3桁の8進数 )
¥uhhhh 16進数hhhhの文字コード ( ¥uと、16進数)

データ型

  • データ型(または型)には、基本データ型(プリミティブ型)と参照型がある。
  • 基本データ型については以下の表に示す。
    参照型には、配列型, クラス型, インタフェース型, 型変数 が含まれる。
  • boolean型が、基本データ型としてサポートされている。
    ※ 論理型は、Javaではboolean型、C++ではbool型。
  • boolean型は、2 つの値 (true または false) のいずれかを設定できる。
  • charが2byte文字を扱うようになっており、C/C++と異なる。
  • byte型が存在する。
  • Javaでは、基本データ型のサイズは環境に依存しない。
    ※ C/C++では、基本データ型のサイズが環境によって異なる場合がある。
基本データ型 (※サイズは環境に依存しない。)
種類 データ型 サイズ 扱える値の種類 扱える値の範囲例
型無し void - - -
論理型 boolean 1 byte true または false -
文字型 char 2 byte 2バイト文字 \u0000 ~ \uffff
整数型 byte 1 byte 整数 -128 ~ 127
short 2 byte 整数 -32768 ~ 32767
int 4 byte 整数 -2147483648 ~ 2147483647
long 8 byte 整数 -9223372036854775808 ~ 9223372036854775807
浮動小数点型 float 4 byte 単精度浮動小数点数 3.4E-38 ~ 3.4E+38
double 8 byte 倍精度浮動小数点数 1.7E-308 ~ 1.7E+308

変数

変数: データを一定期間記憶し、固有の名前(識別子)を付けたもの。

  • 英字、数字、アンダースコア(_)、$ を利用する。※ 最初が数字からはダメ。
  • 長さに制限は無い。
  • 大文字、小文字は区別される。
  • キーワード(予約語)はダメ。
  • 型を指定する。
  • 変数宣言がブロックの先頭でなくても良い。(C++と同様。Cでは、C99から同様。)
  • メソッド(またはブロック)の中で宣言 → ローカル変数。宣言したメソッド(またはブロック)内でのみ利用可能。
  • 変数が特定の名前で参照可能な範囲 → 変数のスコープ。
  • 異なるメソッドのローカル変数に同じ名前をつけてもよいが、異なる変数として扱われることになる。
  • フィールドとローカル変数に同じ名前をつけてもよいが、ローカル変数としての扱いが優先される。
  • ブロックの外側と内側で同じ変数名をつけてもよいが、ブロック内では内側の変数の扱いが優先される。
// (1)変数の宣言
int x, y;   // 宣言
x = 10;     // 代入
x = 50;     // 上書き
y = x;      // 代入 (yは50)
// (2)変数の初期化
int z = 10; // 初期化

演算子

演算子の種類と優先順位 (※ 上:優先度高い。下:優先度低い。)
優先
順位
演算子 補足
※多分に間違いを含むと思われる。当てにしないこと
演算子のグループ 結合規則
1 ( ) 関数呼び出し 関数呼び出し演算子
[ ] (配列の) 添字 添字演算子
. 直接メンバ参照(: ドット) 直接メンバ参照演算子
++ 後置インクリメント 算術演算子
-- 後置デクリメント
2 ! 論理否定 論理演算子
~ 補数 ビット演算子
+ 単項+ (プラス) 算術演算子
- 単項- (マイナス)
++ 前置インクリメント 算術演算子
-- 前置デクリメント
new new演算子 new演算子
( ) 型変換 (: キャスト) 型変換演算子
3 % 剰余 算術演算子
* 乗算
/ 除算
4 + 加算
- 減算
5 << 左シフト ビット演算子
>> 右シフト
>>> 符号無し右シフト
6 > 大なり (より大きい) 関係演算子
>= 大なりイコール(以上)
< 小なり (未満)
<= 小なりイコール (以下)
instanceof 型比較 型比較演算子
7 == 等価 関係演算子
!= 非等価
8 & ビット論理積 ビット演算子
9 ^ ビット排他的論理和
10 | ビット論理和
11 && 論理積 論理演算子
12 || 論理和
13 ? : 条件 条件演算子
14 = 単純代入 単純代入演算子
+= 加算代入 複合代入演算子
-= 減算代入
*= 乗算代入
/= 除算代入
%= 剰余代入
&= ビット論理積代入
^= ビット排他的論理和代入
|= ビット論理和代入
<<= 左シフト代入
>>= 右シフト代入
15 , 順次 順次演算子

<注意点>

インクリメント、デクリメント演算子は、前置と後置で処理が異なることに注意。

public class Sample {

	public static void main(String[] args) {
		int x, y, z;
	    int a[] = { 15, 75 };
	    int b, c;
	    int i;

	    x = 5;
	    y = ++x;      // 加算してから代入 ※ x=x+1; → y=x; と同じ
	    x = 5;
	    z = x++;      // 代入してから加算 ※ z=x; → x=x+1; と同じ
	    System.out.println(y + "\t" + z);    // 結果: y==6, z==5

	    i = 0;
	    b = a[++i];   // 加算してから代入 ※ i=i+1; → b=a[i]; と同じ
	    i = 0;
	    c = a[i++];   // 代入してから加算 ※ c=a[i]; → i=i+1; と同じ
	    System.out.println(b + "\t" + c);    // 結果: b==75, c==15
	}

}

関係演算子や論理演算子による条件において、
C/C++の場合、0以外の値 → 真, 0 → 偽 となる。
Javaの場合、整数型と論理型は厳密に区別され、互いに型変換は不可。→ if(0){ ~;}などは使えない。

ステートメント

Nullステートメント : セミコロン( ; )だけ。実行しても何も起きない。

public class Sample {

	public static void main(String[] args) {
		int[] sample = new int[20];

		int i;
		for (i = 0; i < 10; sample[i++] = 10) {   // 最初の10個の要素に値を代入
			;       // Nullステートメント ※なにもしない
		}
		for (i = 10; i < 20; sample[i++] = 25) {  // 残りの10個の要素に値を代入
			;       // Nullステートメント ※なにもしない
		}
		for (i = 0; i < 20; i++) {
			System.out.println(sample[i]);
		}
	}

}

returnステートメント :メソッドの実行を終了し、コントロールを呼び出し元に戻す。呼び出し元に値(戻り値)を返すこともできる。戻り値が必要ない場合(戻り値がvoid型)は、returnステートメントを省略できる。

public class Sample {

	public static void main(String[] args) {
		int x = 20;
		int y = 30;

		x = sq(x);
		y = sq(y);
		output(x, y);

		return;                   // returnステートメント ※省略可
	}

	public static int sq(int a) {
		return (a * a);           // returnステートメント
	}

	public static void output(int b, int c) {
		System.out.println(b + "\t" + c);
		return;                   // returnステートメント ※省略可
	}

}

式ステートメント :1 つの値, オブジェクト, メソッド, または名前空間に評価できる、1 つ以上のオペランドと 0 個以上の演算子のシーケンスによるステートメント。

public class Sample {

	public static void main(String[] args) {
		int x = 10;
		int y = 20;
		int z = 30;
		int arg1 = 40;
		int arg2 = 50;

		x = (y + 3);           // 式ステートメント ※xは、y+3の値を代入される。
		x++;                   // 式ステートメント ※xは、インクリメントされる。
		x = y = 5;             // 式ステートメント ※xとyの両方に、5が代入される。
		proc(arg1, arg2);      // 式ステートメント ※メソッドを呼び出し、戻り値が返る。
		y = z = (f(x) + 3);    // 式ステートメント ※メソッド呼び出し。

		System.out.println(x + "\t" + y + "\t" + z); // 結果: x==5, y==28, z==28
	}

	public static int proc(int a, int b) {
		return a + b;
	}

	public static int f(int c) {
		return 5 * c;
	}

}

複合ステートメント :波括弧{}で囲まれたステートメントの集合。ブロックのこと。

public class Sample {

    public static void main(String[] args) {
    	int x = 100;
        int sample[] = { 0, 1, 2, 3, 4 };
        int i = 3;

        if (i > 0){            // 複合ステートメントの開始
            sample[i] = x;
            x++;
        }                      // 複合ステートメントの終了

        System.out.println(sample[i] + "\t" + x);  // 結果: sample[i]==100, x==101
    }

}

ifステートメント :条件が真の場合に、指定した文を処理する。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) throws IOException {
		System.out.println("偶数を入力してください。");

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = br.readLine();
		int num = Integer.parseInt(str);

		if (num % 2 == 0) {            // 条件判断
			System.out.println("偶数" + num + "が入力されました。"); // 1文のときは、ブロックにしなくてもいい
		}

		System.out.println("終了します。");
	}

}

if~else :条件が真の場合と、偽の場合に、指定した文を処理する。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) throws IOException {
		System.out.println("整数を入力してください。");

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = br.readLine();
		int num = Integer.parseInt(str);

		if (num % 2 == 0) {      // 条件判断
			System.out.println("偶数" + num + "が入力されました。"); // 1文のときは、ブロックにしなくてもいい
		} else {
			System.out.println("奇数" + num + "が入力されました。"); // 1文のときは、ブロックにしなくてもいい
		}

		System.out.println("終了します。");
	}
}

if~else if ~else :2つ以上の条件を判断し、処理する。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) throws IOException {
		System.out.println("整数を入力してください。");

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = br.readLine();
		int num = Integer.parseInt(str);

		if (num % 2 == 0 && num >= 20) {        // 条件判断
			System.out.println("20以上の偶数" + num + "が入力されました。");     // 1文のときは、ブロックにしなくてもいい
		} else if (num % 2 == 0) {
			System.out.println("20より小さい偶数" + num + "が入力されました。"); // 1文のときは、ブロックにしなくてもいい
		} else {
			System.out.println("奇数" + num + "が入力されました。");             // 1文のときは、ブロックにしなくてもいい
		}

		System.out.println("終了します。");
	}
}

forステートメント :指定した回数だけステートメントを繰り返す

public class Sample {

	public static void main(String[] args) {
		int sum = 0;

		for (int i = 1; i <= 10; i++) {   // forステートメント
			sum += i;
		}

		System.out.println("1から10までの数の合計は" + sum + "です。");  // 結果: sum==55
	}

}

whileステートメント :指定した式が false になるまでステートメントを繰り返す。

public class Sample {

	public static void main(String[] args) {
		String str1 = "destiny";
		String str2 = "honesty";

		StringBuffer sb = new StringBuffer(str1);

		System.out.println(sb);                // 結果: destiny

		int i = 6;
		while (i >= 0) {                       // whileステートメント
			sb.setCharAt(i, str2.charAt(i));   // string2 から sb に文字をコピー
			i--;
		}

		System.out.println(sb);                // 結果: honesty
	}

}

do-whileステートメント :指定した式が false になるまでステートメントを繰り返す。ループの本体は少なくとも一度は常に実行される。

public class Sample {

	public static void main(String[] args) {
		String str1 = "destiny";
		String str2 = "honesty";

		StringBuffer sb = new StringBuffer(str1);

		System.out.println(sb);                // 結果: destiny

		int i = 6;

		do{                                    // do-whileステートメント
			sb.setCharAt(i, str2.charAt(i));   // string2 から sb に文字をコピー
			i--;
		} while (i >= 0);

		System.out.println(sb);                // 結果: honesty
	}

}

switchステートメント :条件式の値に応じて、多分岐を行う。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) throws IOException {
		System.out.println("整数を入力してください。");

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = br.readLine();
		int a = Integer.parseInt(str);

		switch (a) {           // switchステートメント
		case 1:
			System.out.println("1が入力されました。");
			break;
		case 2:
			System.out.println("2が入力されました。");
			break;
		case 3:
		case 4:
			System.out.println("3または4が入力されました。");
			break;
		case 5:
			System.out.println("5が入力されました。");
			break;
		default:               // defaultの処理が必要ない場合は省略可能
			System.out.println("1~5以外の整数が入力されました。");
			break;
		}
	}

}

continueステートメント :最も内側の、do, for, while のステートメントにおいて、残りのステートメントを実行せず、次のループに移る。

public class Sample {

	public static void main(String[] args) {
		int sum = 0;
		for (int i = 0; i <= 10; i++) {
			if (i % 2 != 0) {
				continue;                   // continueステートメント
			}
			sum += i;
		}

		System.out.println("0から10までの偶数の数の合計は" + sum);  // 結果: sum==30
	}

}

breakステートメント :最も内側の、do, for, switch または while のステートメントの実行を終了する。

public class Sample {

	public static void main(String[] args) {
		boolean myflag = false;
		int x = 0;
		int y = 0;

		for (int i = 0; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				if (x * y == 50) {
					myflag = true;
					break;                   // breakステートメント
				}
				x++;
			}
			if (myflag) {
				break;                       // breakステートメント
			}
			y++;
		}

		System.out.println(x + "\t" + y);    // 結果: x==25, y==2
	}

}

<制御をラベルに移す: gotoステートメントの代替>
Javaはgotoステートメントをサポートしていない(予約語にはある)
代わりに、ラベル指定付きのbreak文を使うことで、多重ループから一気に抜けることが可能。

public class Sample {

	public static void main(String[] args) {
		int x = 0;
		int y = 0;

		mylabel: for (int i = 0; i < 10; i++) {   // ラベルの使用
			for (int j = 0; j < 10; j++) {
				if (x * y == 50) {
					break mylabel;                // 多重ループから一気に抜ける
				}
				x++;
			}
			y++;
		}

		System.out.println(x + "\t" + y);         // 結果: x==25, y==2
	}

}

配列

配列 : 同じ型の値を複数まとめて記憶する機能。※配列変数は、参照型の変数

public class Sample {

    public static void main(String[] args) {
        // オブジェクトまたは変数が変更できないことを指定するにはfinalが使用できる。
        final int NUM = 3;              // Javaでは、constキーワードは使えない(予約語にはある)。

        // (1) 配列変数の宣言 ※どちらでも可
        int sample1[];                  // 配列変数の宣言(その1)
        int[] sample2;                  // 配列変数の宣言(その2)

        // (2) 配列要素の領域確保 ※どちらでも可
        sample1 = new int[3];           // 要素数を利用
        sample2 = new int[NUM];         // finalキーワードによる定数の利用

        // (3) 配列要素への値の代入 ※添字を利用
        sample1[0] = 25;
        sample1[1] = 57;
        sample1[2] = 12;

        sample2[0] = 36;
        sample2[1] = 92;
        sample2[2] = 43;

        // 出力
        for (int i = 0; i < NUM; i++) {
            System.out.println(sample1[i] + "\t" + sample2[i]);
        }

        // ---------------------------------------------------------------------------------------
        // (1) 配列変数の宣言, 配列要素の領域確保 を同時に行う ※どちらでも可
        int sample3[] = new int[3];
        int[] sample4 = new int[3];

        // (2) 配列要素への値の代入
        sample3[0] = 25;
        sample3[1] = 57;
        sample3[2] = 12;

        sample4[0] = 36;
        sample4[1] = 92;
        sample4[2] = 43;

        // 出力
        for (int i = 0; i < NUM; i++) {
            System.out.println(sample3[i] + "\t" + sample4[i]);
        }

        // ---------------------------------------------------------------------------------------
        // (1) 配列変数の宣言, 配列要素の領域確保, 配列要素の初期化 を同時に行う ※どちらでも可
        int sample5[] = { 25, 57, 12 }; // 初期化子を利用(25,67,12など)
        int[] sample6 = { 36, 92, 43 };

        // 出力
        for (int i = 0; i < NUM; i++) {
            System.out.println(sample5[i] + "\t" + sample6[i]);
        }
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

    public static void main(String[] args) throws IOException {
        System.out.println("いくつの整数データを入力しますか?");

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        int res1 = Integer.parseInt(str);

        // 配列変数の宣言, 配列要素の領域確保 を同時に行う
        int[] data = new int[res1];

        System.out.println(res1 + "個の整数データを入力してください。");

        // 入力
        for (int i = 0; i < data.length; i++) {       // 配列名.length は配列の長さ(配列の要素数)を示す。
            System.out.println((i + 1) + "番目の整数データはいくつですか?");
            str = br.readLine();
            int res2 = Integer.parseInt(str);
            data[i] = res2;
        }

        // 出力
        System.out.println("整数データは全部で" + data.length + "個です。");          // 配列名.length
        for (int i = 0; i < data.length; i++) {                                       // 配列名.length
            System.out.println((i + 1) + "番目の整数データは" + data[i] + "です。");
        }
    }
}
public class Sample {

	public static void main(String[] args) {
		int[] data1 = { 57, 38, 71 };
		int[] data2;

		// 配列変数に、配列変数を代入 ※data2が、data1が指している配列を挿す
		data2 = data1; // data1もdata2も、同じ 配列要素の領域 を指す

		for (int i = 0; i < data1.length; i++) {
			System.out.println(data1[i] + "\t" + data2[i]);
		}

		// data1の要素の値を変更すると、data2の要素の値も同じように変わる。※同一であるため
		data1[1] = 777;
		for (int i = 0; i < data1.length; i++) {
			System.out.println(data1[i] + "\t" + data2[i]);
		}

		// data2の要素の値を変更すると、data1の要素の値も同じように変わる。※同一であるため
		data2[0] = 333;
		for (int i = 0; i < data1.length; i++) {
			System.out.println(data1[i] + "\t" + data2[i]);
		}
	}
}

多次元配列 : 配列そのものを要素として持つ配列。

public class Sample {

    public static void main(String[] args) {
        // (1) 配列変数の宣言 ※どちらでも可
        int data1[][];
        int[][] data2;

        // (2) 配列要素の領域確保
        data1 = new int[2][3];
        data2 = new int[2][3];

        // (3) 配列要素への値の代入  ※data2は略
        data1[0][0] = 25;
        data1[0][1] = 57;
        data1[0][2] = 12;

        data1[1][0] = 36;
        data1[1][1] = 92;
        data1[1][2] = 43;

        // 出力
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.println(data1[i][j]);
            }
        }

        // ---------------------------------------------------------------------------------------
        // (1) 配列変数の宣言, 配列要素の領域確保 を同時に行う ※どちらでも可
        int data3[][] = new int[2][3];
        int[][] data4 = new int[2][3];

        // (2) 配列要素への値の代入  ※data4は略
        data3[0][0] = 25;
        data3[0][1] = 57;
        data3[0][2] = 12;

        data3[1][0] = 36;
        data3[1][1] = 92;
        data3[1][2] = 43;

        // 出力
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.println(data3[i][j]);
            }
        }

        // ---------------------------------------------------------------------------------------
        // (1) 配列変数の宣言, 配列要素の領域確保, 配列要素の初期化 を同時に行う ※どちらでも可
        int data5[][] = { { 25, 57, 12 }, { 36, 92, 43 } };
        int[][] data6 = { { 25, 57, 12 }, { 36, 92, 43 } };

        // 出力
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.println(data5[i][j] + "\t" + data6[i][j]);
            }
        }

        // ---------------------------------------------------------------------------------------
        // "要素数が様々な配列"の配列の場合
        // (1) 配列変数の宣言, 配列要素の領域確保, 配列要素の初期化 を同時に行う ※どちらでも可
        int data7[][] = { { 25, 57, 12, 27 }, { 36, 92, 43 },
                { 57, 22, 90, 51, 20 }, { 23, 12 } };

        int[][] data8 = { { 25, 57, 12, 27 }, { 36, 92, 43 },
                { 57, 22, 90, 51, 20 }, { 23, 12 } };

        // 出力  ※data8は略
        for (int i = 0; i < data7.length; i++) {        // 配列名.lengthで配列全体の長さを示す
            for (int j = 0; j < data7[i].length; j++) { // 配列名[添字].lengthで個々の配列の長さを示す
                System.out.println(data7[i][j]);
            }
        }
    }
}

オブジェクトの配列

class Ship {
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			this.shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

public class Sample {

	public static void main(String[] args) {
		// (1)オブジェクトの配列の作成
		Ship[] ship1 = new Ship[3];    // 配列変数の宣言と、配列要素の領域確保を同時に行う

		for (int i = 0; i < ship1.length; i++) {
			ship1[i] = new Ship();     // オブジェクトを作成し、配列要素がオブジェクトを指すようにする
		}

		// (2)オブジェクトの配列の作成
		Ship ship2[];                  // 配列変数の宣言
		ship2 = new Ship[3];           // 配列要素の領域確保

		ship2[0] = new Ship();         // オブジェクトを作成し、配列要素がオブジェクトを指すようにする
		ship2[1] = new Ship();
		ship2[2] = new Ship();
	}
}

クラス

  • クラスとは、クラスベースのオブジェクト指向においてオブジェクトの設計図にあたるもの。
  • クラスから生成したオブジェクトのことをインスタンスという。
  • クラス型の変数参照型の変数
  • カプセル化 :データとそれを操作する手続きを一体化し、オブジェクト内の仕様や構造を外部から隠蔽すること。
  • クラスは、フィールドメソッドをメンバとすることができる。
  • クラスは、クラス・インタフェースをネストできる。
  • Java, C++/CLI, C#では、メンバ変数をフィールドと呼ぶ。フィ-ルドは、クラスにおけるデータ, 性質を示す。
    ※ C++ではメンバ変数をデータメンバと呼ぶ。規格上、フィールドとは呼ばないので注意。
    ※ C/C++では、"フィールド"とは"ビット・フィールド"を略した呼称になるので、混同しないように注意。
  • Java, C++/CLI, C#では、メンバ関数をメソッドと呼ぶ。メソッドは、クラスにおける機能, 手続きを示す。
    ※ C++ではメンバ関数は、そのままメンバ関数と呼ぶ。規格上、メソッドとは呼ばないので注意。
// Shipクラスの宣言・定義
class Ship {
    // フィールド  (データ, 性質を示す)
    private int shipNum;
    private double weight;

    // メソッド  (機能, 手続きを示す)
    public void setShipNum(int num) {
        if (num >= 1) {
            this.shipNum = num;  // オブジェクト自身を指す"this"は省略可
            System.out.println("適切な値" + num + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }

    public void setWeight(double wt) {
        if (wt >= 0) {
            weight = wt;         // this は省略している
            System.out.println("適切な値" + wt + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }

    public int getShipNum() {
        return shipNum;          // this は省略している
    }

    public double getWeight() {
        return weight;           // this は省略している
    }

    public void go() {
        System.out.println("進みます");
    }
}

public class Sample {

    public static void main(String[] args) {
        // オブジェクトの作成 (その1)
        Ship ship1;              // Shipクラス型の変数ship1の宣言
        ship1 = new Ship();      // オブジェクト(インスタンス)を作成し、クラス型の変数ship1へ代入

        // オブジェクトの作成 (その2)
        Ship ship2 = new Ship(); // オブジェクト(インスタンス)を作成し、クラス型の変数ship2へ代入を同時に行う

        ship1.setShipNum(10);  // 実引数10で、メソッド呼び出し
        ship1.setWeight(3.5);  // 実引数3.5で、メソッド呼び出し

        // 実引数無しで、メソッド呼び出し
        System.out.println("船の番号は" + ship1.getShipNum());
        System.out.println("船の排水トン数は" + ship1.getWeight() + "トン");
        ship1.go();
    }
}

修飾子

フィールド、メソッドのアクセス修飾子

  • public: 全てのクラス、全てのパッケージからアクセス可能。
  • protected: 同じクラス内と派生クラス(サブクラス)からアクセス可能。※但し、同一パッケージの場合、他のクラスからもアクセス可能。
  • private: 同じクラス内からのみアクセス可能。
  • アクセス修飾子無し: 同じパッケージ内からアクセス可能。
フィールド、メソッドのアクセス修飾子 (○:アクセス可。 ×:アクセス不可)
アクセス
修飾子
同じ
パッケージ
他の
パッケージ
アクセス可能な場所
同じ
クラス
派生
クラス
他の
クラス
派生
クラス
他の
クラス
public 全てのパッケージの、全てのクラス
protected × 同じクラス内と派生クラス
※但し、同一パッケージの場合、他のクラスからもアクセス可能。
private × × × × 同じクラス内からのみ
アクセス
修飾子
無し
× × 同じパッケージ内

クラスの修飾子

  • クラスにおける修飾子は、public(※アクセス修飾子), アクセス修飾子無し, final, abstract が利用可能。
    ※private, protectedは利用不可。
クラスの修飾子
修飾子 説明
public  ※アクセス修飾子
全てのパッケージの、全てのクラスからアクセス可能
アクセス修飾子無し 同じパッケージ内のクラスからアクセス可能
abstruct 抽象クラスとなり、インスタンス化できない
final サブクラスに拡張できない

インタフェースのアクセス修飾子

  • インタフェースのアクセス修飾子は、無指定(アクセス修飾子無し) public とする。

メソッドのオーバーロード

  • 同じクラスに、同じ名前のメソッドを複数定義し、利用時にプログラムの文脈に応じて選択することで、複数の動作を行わせる仕組み(多重定義)のこと。
  • 多態性を実現する一つの手段。
    ※ 多態性(ポリモーフィズム)とは、プログラミング言語の型システムの性質を表すもので、プログラミング言語の各要素(定数、変数、式、オブジェクト、関数、メソッドなど)についてそれらが複数の型に属することを許すという性質を指す。
  • 同じメソッド名で引数の型や数が異なるメソッドを作成する。
  • メソッド内で同じような処理も、異なるような処理もできる。
class Ship {
    private int shipNum;
    private double weight;
 
    public void set(int num) {                      // メソッドのオーバーロード
        if (num >= 1) {
            shipNum = num;
            System.out.println("適切な値" + num + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }
 
    public void set(double wt) {                    // メソッドのオーバーロード
        if (wt >= 0) {
            weight = wt;
            System.out.println("適切な値" + wt + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }
 
    public void set(int num, double wt) {           // メソッドのオーバーロード
        if (num >= 1 && wt >= 0) {
            shipNum = num;
            weight = wt;
            System.out.println("適切な値" + num + "と" + wt + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }
 
    public int getShipNum() {
        return shipNum;
    }
 
    public double getWeight() {
        return weight;
    }
 
    public void go() {
        System.out.println("進みます");
    }
}
 
public class Sample {
 
    public static void main(String[] args) {
        Ship ship = new Ship();
         
        // メソッドをオーバーロードすると、同じメソッド名で、同じような処理も異なるような処理もできる
        ship.set(10);        // 実引数10で、メソッド呼び出し
        ship.set(3.5);       // 実引数3.5で、メソッド呼び出し
 
        System.out.println("船の番号は" + ship.getShipNum());                  // 結果: 10
        System.out.println("船の排水トン数は" + ship.getWeight() + "トン");    // 結果: 3.5
 
        ship.set(20, 5.5);   // 実引数20と5.5で、メソッド呼び出し
 
        System.out.println("船の番号は" + ship.getShipNum());                  // 結果: 20
        System.out.println("船の排水トン数は" + ship.getWeight() + "トン");    // 結果: 5.5
    }
}

コンストラクタ

  • オブジェクトを生成する際に呼び出されて、内容の初期化などを行なう関数のこと。
  • 引数を指定せずに呼び出せるコンストラクタを、デフォルトコンストラクタという。
      → 例えば、全ての引数にデフォルト引数がある場合は、引数を指定せずに呼び出せるので、デフォルトコンストラクタ。
  • コンストラクタを省略した場合は、コンパイラが用意したデフォルトコンストラクタが呼び出される。
      ※ 結果論であり、デフォルトコンストラクタの定義ではないので注意。
  • 関数(コンストラクタ)名を、クラス名と同じものにする。
  • 戻り値を持たない。※void型の指定もしない。
  • 引数を持つことができる(無くても可)。よって、オーバーロードによる複数定義が可能。
// Shipクラスの宣言・定義
class Ship {
	private int shipNum;
	private double weight;

	// コンストラクタ ※コンストラクタ名はクラス名と同じにする。戻り値を持たない(void型の指定もしない)。
	public Ship() {
		shipNum = 1;   // フィールドを初期化しなかった場合は、デフォルト値で自動的に初期化される。
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

public class Sample {

	public static void main(String[] args) {
		// オブジェクト作成
		Ship ship = new Ship();     // オブジェクト作成時にコンストラクタが呼び出される

		System.out.println("船の番号は" + ship.getShipNum());                // 結果: 1
		System.out.println("船の排水トン数は" + ship.getWeight() + "トン");  // 結果: 1.0

		ship.setShipNum(10);
		ship.setWeight(3.5);

		System.out.println("船の番号は" + ship.getShipNum());                // 結果: 10
		System.out.println("船の排水トン数は" + ship.getWeight() + "トン");  // 結果: 3.5
		ship.go();
	}
}
// Shipクラスの宣言・定義
class Ship {
	private int shipNum;
	private double weight;

	// 引数なしのコンストラクタ
	public Ship() {                     // コンストラクタのオーバーロード
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	// 引数2つのコンストラクタ
	public Ship(int num, double wt) {   // コンストラクタのオーバーロード
		this();   // 最初のステートメントに限り、他のコンストラクタを呼び出すことができる。引数ありも可。
		shipNum = num;
		weight = wt;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

public class Sample {

	public static void main(String[] args) {
		// オブジェクト作成
		Ship ship1 = new Ship();                 // 引数なしのコンストラクタが呼び出される

		System.out.println("船の番号は" + ship1.getShipNum());                // 結果: 1
		System.out.println("船の排水トン数は" + ship1.getWeight() + "トン");  // 結果: 1.0

		// オブジェクト作成
		Ship ship2 = new Ship(10, 3.5);          // 引数2つのコンストラクタが呼び出される

		System.out.println("船の番号は" + ship2.getShipNum());                // 結果: 10
		System.out.println("船の排水トン数は" + ship2.getWeight() + "トン");  // 結果: 3.5
	}
}

フィールドの初期値

  • フィールドの値は、インスタンス変数とクラス変数ともに、自分で初期化しなくても、それぞれの型に応じたデフォルト値(初期値)で初期化される。
    ※インスタンス変数:オブジェクトに関連づけられているフィールドのこと。
    ※クラス変数:クラスに関連づけられているフィールドのこと。
フィールドの、型と初期値
初期値
整数型 (byte, short, int, long) 0
浮動小数点型 (float, double) 0.0
文字型 (char) '\u0000' (空文字)
論理型 (boolean) false
参照型 (配列型, クラス型など) null
class Test {
	// フィールドは、インスタンス変数とクラス変数ともに、自動的に初期化される。
	// ※ここではインスタンス変数のみの例だが、クラス変数でも初期化される。

    // 整数型
    public byte bt;
    public short sh;
    public int i;
    public long lg;

    // 浮動小数点型
    public float fl;
    public double db;

    // 文字型
    public char ch;

    // 論理型
    public boolean bln;

    // 参照型
    public int[] intArray;
    public String str;
}

public class Sample {

    public static void main(String[] args) {
        Test test = new Test();

        // フィールドは、自分で初期化しなくても、自動的にデフォルト値で初期化される。
        // 整数型
        System.out.println(test.bt);       // 0
        System.out.println(test.sh);       // 0
        System.out.println(test.i);        // 0
        System.out.println(test.lg);       // 0

        // 浮動小数点型
        System.out.println(test.fl);       // 0.0
        System.out.println(test.db);       // 0.0

        // 文字型
        System.out.println(test.ch);       // (空文字)

        // 論理型
        System.out.println(test.bln);      // false

        // 参照型
        System.out.println(test.intArray); // null
        System.out.println(test.str);      // null

        // ローカル変数は、自動的に初期化されない。自分で値を設定する。
        int localVar = 0;
        System.out.println(localVar);      // 0
    }
}

インスタンス変数, インスタンスメソッド 及び クラス変数, クラスメソッド

  • インスタンス変数: オブジェクトに関連づけられているフィールドのこと。
    オブジェクトのインスタンスごとに割り当てられた変数。
  • インスタンスメソッド: オブジェクトに関連づけられているメソッドのこと。
    オブジェクトのインスタンスごとに割り当てられたメソッド。メソッド内でのthisキーワードは使用可能。
    ※ インスタンスメソッドでは、インスタンス変数や別のインスタンスメソッド、クラス変数やクラスメソッドにアクセスできる。
  • クラス変数: クラスに関連づけられているフィールドのこと。
    同一クラス・派生クラスで共有される変数。static修飾子を使用する。
  • クラスメソッド: クラスに関連づけられているメソッドのこと。
    同一クラス・派生クラスで共有されるメソッド。static修飾子を使用する。メソッド内でのthisキーワードは使用不可。
    ※ クラスメソッドでは、クラス変数や別のクラスメソッドにはアクセスできるが、インスタンス変数やインスタンスメソッドにはアクセスできない。
// Shipクラスの宣言・定義
class Ship {
	// クラス変数
	private static int totalShip = 10; // 任意の初期化ができる。設定無しの場合、デフォルト値で自動的に初期化される。

	// インスタンス変数
	private int shipNum;
	private double weight;

	// コンストラクタ
	public Ship() {
		shipNum = 1;                   // フィールドを初期化しなかった場合は、デフォルト値で自動的に初期化される。
		weight = 1.0;
		System.out.println("船を用意しました。");
		totalShip++;                   // クラス変数の利用
	}

	// クラスメソッド
	public static int getTotalShip() {
		return totalShip;              // クラスメソッドでは、オブジェクト自身を指す"this"は使用不可
	}

	// インスタンスメソッド
	public void setShipNum(int num) {
		if (num >= 1) {
			this.shipNum = num;        // インスタンスメソッドでは、オブジェクト自身を指す"this"は使用可能
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	// インスタンスメソッド
	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;               // this は省略している
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	// インスタンスメソッド
	public int getShipNum() {
		return shipNum;                // this は省略している
	}

	// インスタンスメソッド
	public double getWeight() {
		return weight;                 // this は省略している
	}

	// インスタンスメソッド
	public void go() {
		System.out.println("進みます");
	}
}

public class Sample {
 
    public static void main(String[] args) {
        // オブジェクトが作成されていなくても、クラス変数やクラスメソッドは利用できる。(privateは除く)
        System.out.println("船の総数は" + Ship.getTotalShip() + "隻");        // 結果: 10
 
        // オブジェクト作成
        Ship ship = new Ship();
 
        System.out.println("船の総数は" + Ship.getTotalShip() + "隻");        // 結果: 11
 
        ship.setShipNum(10);
        ship.setWeight(3.5);
 
        System.out.println("船の番号は" + ship.getShipNum());                 // 結果: 10
        System.out.println("船の排水トン数は" + ship.getWeight() + "トン");   // 結果: 3.5
        ship.go();
    }
}

クラス型の変数への代入

  • オブジェクトを指しているクラス型の変数へ、同じクラス型の変数を代入することができる。この時、それぞれの変数は同じオブジェクトを指すようになる。
  • クラス型の変数へ null を代入すると、どのオブジェクトも指し示さなくなる。
  • どこからも参照されなくなったオブジェクトは、ガベージコレクションの対象となる。JVM(Java仮想マシン, Java virtual machine, Java VM) 内におけるガベージコレクションの動作のタイミングで、そのメモリ領域を解放する。
  • ガベージコレクション (garbage collection) :  "ガーベジコレクション" と表記する場合もある。プログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能。
    ※garbageの発音記号は gɑ'ːrbidʒ なので、ガァー(ル)ビィヂに近い発音。便宜上、敢えてカタカナで表記する場合は、ガベージよりもガーベジのほうが良いと個人的には思うのだが、公式サイトではガベージ表記がほとんど・・・。困ったもんだ。
  • オブジェクトが破棄されるときは、finalizeメソッドが自動的に呼び出される。finalizeメソッドには終了処理などを記述する。但し実行されるタイミングは、JVMによる。
class Ship {
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			this.shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

public class Sample {

	public static void main(String[] args) {
		Ship ship1;         // Shipクラス型の変数ship1の宣言
		ship1 = new Ship(); // オブジェクトを作成し、クラス型の変数ship1へ代入

		Ship ship2;         // Shipクラス型の変数ship2の宣言

		ship2 = ship1;      // ship2へship1の代入 ※ship1とship2は、同じオブジェクトを指すようになる

		System.out.println("船の番号は" + ship1.getShipNum());                // 結果: 1
		System.out.println("船の排水トン数は" + ship1.getWeight() + "トン");  // 結果: 1.0

		System.out.println("船の番号は" + ship2.getShipNum());                // 結果: 1
		System.out.println("船の排水トン数は" + ship2.getWeight() + "トン");  // 結果: 1.0

		// 代入した方、代入された方の、どちらかのオブジェクトのフィールドの値を変更すると、
		// もう一方のフィールドの値も変更される。※同じオブジェクトを指しているため
		ship1.setShipNum(20);     // ship1のフィールドの値の変更
		ship1.setWeight(20.5);

		System.out.println("船の番号は" + ship1.getShipNum());                // 結果: 20
		System.out.println("船の排水トン数は" + ship1.getWeight() + "トン");  // 結果: 20.5

		System.out.println("船の番号は" + ship2.getShipNum());                // 結果: 20
		System.out.println("船の排水トン数は" + ship2.getWeight() + "トン");  // 結果: 20.5

		ship1 = null;  // 全てのクラス型の変数の、オブジェクト参照が無くなるまでは、オブジェクトは破棄されない。

		System.out.println("船の番号は" + ship2.getShipNum());                // 結果: 20
		System.out.println("船の排水トン数は" + ship2.getWeight() + "トン");  // 結果: 20.5

		ship2 = null;  // この時点で、オブジェクトがガベージコレクションの対象となる。※実行はまた別。
	}
}

列挙型

列挙型enumは、staticキーワードの有り無しに関わらず、基本的にstaticである。
列挙子は、基本的にstaticであり、 final指定の変数(定数)と扱い方は似ている。(クラス内のstatic final変数と似ている)

このため、例えば、あるクラス内に定義した場合、その所属するクラスをインスタンス化しなくても、他のクラスから利用できる。
ただし、アクセス修飾子の影響は受ける。

public class Sample {

    public static void main(String[] args) {
        writeColor(ColorType.BLUE);
    }

    // 列挙型名:ColorType
protected enum ColorType { RED, BLUE, YELLOW // 列挙子リスト
} protected static void writeColor(ColorType color){ // 仮引数:列挙型ColorTypeの変数
String text = null; switch (color){ case RED: // switch文では、ColorType.REDではなくREDで良い ※if文などの条件式では使えない
text = ""; break; case BLUE: text = ""; break; case YELLOW: text = ""; break; // 省略可
} System.out.println(text); // 結果:
} }

クラスライブラリ

Objectクラス

  • Objectクラスは、クラス階層のルートである。
  • 全てのクラスは、スーパークラスとしてObjectを持つ。
  • 配列を含む全てのオブジェクトはこのクラスのメソッドを実装する。
Objectクラスのメソッド例 ※詳細は公式のJava APIを参照のこと
メソッド 説明
protected Object
 clone()
このオブジェクトのコピーを作成して、返す。
boolean
 equals(Object obj)
このオブジェクトと他のオブジェクトが等しいかどうかを示す。
protected void
 finalize()
このオブジェクトへの参照はもうないとガベージコレクションによって判断されたときに、ガベージコレクタによって呼び出される。
Class
 getClass()
この Object の実行時クラスを返す。
int
 hashCode()
オブジェクトのハッシュコード値を返す。
void
 notify()
このオブジェクトのモニターで待機中のスレッドを 1 つ再開する。
void
 notifyAll()
このオブジェクトのモニターで待機中のすべてのスレッドを再開する。
String
 toString()
オブジェクトの文字列表現を返す。
void
 wait()
別のスレッドがこのオブジェクトの notify() メソッドまたは notifyAll() メソッドを呼び出すまで、現在のスレッドを待機させる。
void
 wait(long timeout)
別のスレッドがこのオブジェクトの notify() メソッドまたは notifyAll() メソッドを呼び出すか、指定された時間が経過するまで、現在のスレッドを待機させる。
void
 wait(long timeout, int nanos)
別のスレッドがこのオブジェクトの notify() メソッドまたは notifyAll() メソッドを呼び出すか、ほかのスレッドが現在のスレッドに割り込みをかけたり、指定された量の実時間が経過するまで、現在のスレッドを待機させる。
class Ship {
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			this.shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}

	// Objectクラスからのオーバーライド
	public String toString() {
		String str = "shipNum = " + shipNum + ", " + "weight = " + weight;
		return str;
	}
}

class Submarine extends Ship {
	int torpedoNum;

	public Submarine() {
		int torpedoNum = 4;
		System.out.println("潜水艦を用意しました。");
	}
}

public class Sample {

	public static void main(String[] args) {
		// -------------------------------------------------------------------------------
		Ship ship = new Ship(); // 全てのクラスはObjectクラスをスーパークラスに持つ

		/*
		 * println()の引数にオブジェクト(null以外)を渡すと、 Objectクラスから継承したtoStringメソッドが呼び出される
		 */

		// toString()メソッドを、オーバーライドしなかった場合
		// System.out.println(ship); 結果: Ship@数値

		// toString()メソッドを、オーバーライドした場合
		System.out.println(ship); // 結果: shipNum = 1, weight = 1.0

		// -------------------------------------------------------------------------------
		Ship ship1 = new Ship();
		Ship ship2 = new Ship();

		Ship ship3;
		ship3 = ship1;

		boolean bl = ship1.equals(ship2);
		System.out.println(bl);                 // 結果: false
		bl = ship1.equals(ship3);
		System.out.println(bl);                 // 結果: true

		// -------------------------------------------------------------------------------
		Ship[] ship4 = new Ship[3];

		ship4[0] = new Ship();
		ship4[1] = new Submarine();
		ship4[2] = new Ship();

		for (int i = 0; i < ship4.length; i++) {
			Class cl = ship4[i].getClass();      // Objectの実行時クラスを返す
			System.out.println(cl);
		}
	}
}

Stringクラス

  • String クラスは文字列を表す。 "abc" などのリテラル文字列は全て、このクラスのインスタンスとして実行される。
  • 文字列は定数であり、この値を作成したあとに変更はできない。
    ※ 文字列バッファーは可変文字列をサポートする。
Stringクラスのメソッド例 ※詳細は公式のJava APIを参照のこと
メソッド 説明
char
 charAt(int index)
指定されたインデックスの char 値を返す。
String
 concat(String str)
指定された文字列をこの文字列の最後に連結する。
boolean
 equals(Object anObject)
この文字列と指定されたオブジェクトを比較する。
int
 indexOf(int ch)
この文字列内で、指定された文字が最初に出現する位置のインデックスを返す。
int
 indexOf(int ch, int fromIndex)
この文字列内で、指定されたインデックスから検索を開始し、指定された文字が最初に出現する位置のインデックスを返す。
boolean
 isEmpty()
length() が 0 の場合にのみ、true を返す。
int
 lastIndexOf(int ch)
この文字列内で、指定された文字が最後に出現する位置のインデックスを返す。
int
 lastIndexOf(int ch, int fromIndex)
この文字列内で、指定された文字が最後に出現する位置のインデックスを返す (検索は指定されたインデックスから開始され、先頭方向に行われる)。
int
 length()
この文字列の長さを返す。
String
 toString()
このオブジェクト (すでに文字列である) 自身が返される。
String
 toLowerCase()
デフォルトロケールの規則を使って、この String 内のすべての文字を小文字に変換する。
String
 toUpperCase()
デフォルトロケールの規則を使って、この String 内のすべての文字を大文字に変換する。
String str = "abc";

// 上のコードと下のコードは同じ。

char data[] = {'a', 'b', 'c'};
String str = new String(data);
public class Sample {

	public static void main(String[] args) {
		String str = "hello";

		char ch = str.charAt(1);
		System.out.println(ch);               // 結果: e

		String str2 = str.concat(",world");   // strが変更されるわけではない。
		System.out.println(str2);             // 結果: hello,world

		int index = str.indexOf('e');         // 検索文字が見つからない場合は -1 を返す
		System.out.println(index);            // 結果: 1

		index = str.indexOf('l', 3);          // 後尾に向かって文字検索。見つからない場合は -1 を返す
		System.out.println(index);            // 結果: 3

		String str3 = "";
		boolean bl = str3.isEmpty();
		System.out.println(bl);               // 結果: true

		int lastIndex = str.lastIndexOf('l'); // 検索文字が見つからない場合は -1 を返す
		System.out.println(lastIndex);        // 結果: 3

		lastIndex = str.lastIndexOf('l', 2);  // 先頭に向かって文字検索。見つからない場合は -1 を返す
		System.out.println(lastIndex);        // 結果: 2

		System.out.println(str.length());     // 結果: 5

		String str4 = str.toString();
		System.out.println(str4);             // 結果: hello

		String str5 = "HELLO";
		String str6 = str5.toLowerCase();
		System.out.println(str6);             // 結果: hello

		String str7 = str.toUpperCase();
		System.out.println(str7);             // 結果: HELLO
	}
}

StringBufferクラス

  • StringBufferクラスは、スレッドセーフな可変の文字列である。
  • String に似ているが、変更できる点が異なる。
  • 文字列の長さと内容は特定のメソッドの呼び出しにより変更できる。
StringBufferクラスのメソッド例 ※詳細は公式のJava APIを参照のこと
メソッド 説明
StringBuffer
 append(char c)
char 引数の文字列表現をこのシーケンスに追加する。
StringBuffer
 append(char[] str)
char 配列引数の文字列表現をこのシーケンスに追加する。
StringBuffer
 append(String str)
指定された文字列をこの文字シーケンスに追加する。
StringBuffer
 append(StringBuffer sb)
指定された StringBuffer をこのシーケンスに追加する。
int
 capacity()
現在の容量を返す。
char
 charAt(int index)
このシーケンス内の指定されたインデックスの char 値を返す。
StringBuffer
 delete(int start, int end)
このシーケンスの部分文字列内の文字を削除する。
StringBuffer
 deleteCharAt(int index)
このシーケンス内の指定された位置にある char を削除する。
int
 indexOf(String str)
この文字列内で、指定された部分文字列が最初に出現する位置のインデックスを返す。
StringBuffer
 insert(int offset, char c)
char 引数の文字列表現をこのシーケンスに挿入する。
StringBuffer
 insert(int offset, String str)
文字列をこの文字シーケンスに挿入する。
int
 length()
長さ (文字数) を返す。
StringBuffer
 replace(int start, int end, String str)
このシーケンスの部分文字列内の文字を、指定された String 内の文字で置き換える。
StringBuffer
 reverse()
この文字シーケンスを、シーケンスの順序を逆にしたもので置き換える。
String
 toString()
このシーケンス内のデータを表す文字列を返す。
public class Sample {

	public static void main(String[] args) {
		String str1 = "hello";
		String str2 = "world";

		StringBuffer sb = new StringBuffer(str1);

		sb.append(str2);         // 文字列を追加
		System.out.println(sb);  // 結果: helloworld

		sb.insert(5, ", ");      // 文字列を挿入
		System.out.println(sb);  // 結果: hello, world
	}
}

Mathクラス

  • Mathクラスは、指数関数、対数関数、平方根、および三角関数といった基本的な数値処理を実行するためのメソッドを含んでいる。
Mathクラスの フィールド, メソッド例 ※詳細は公式のJava APIを参照のこと
フィールドとメソッド 説明
static double
 E
自然対数の底 e にもっとも近い double 値。
static double
 PI
円周とその直径の比 pi にもっとも近い double 値。
static double
 abs(double a)
double 値の絶対値を返す。
static int
 abs(int a)
int 値の絶対値を返す。
static double
 cbrt(double a)
double 値の立方根を返す。
static double
 ceil(double a)
引数の値以上で、計算上の整数と等しい、最小の (負の無限大にもっとも近い) double 値を返す。
static double
 cos(double a)
指定された角度の余弦 (コサイン) を返す。
static double
 floor(double a)
引数の値以下で、計算上の整数と等しい、最大の (正の無限大にもっとも近い) double 値を返す。
static double
 log(double a)
指定された double 値の自然対数 (底は e) を返す。
static double
 max(double a, double b)
2つの double 値のうち大きいほうを返す。
static int
 max(int a, int b)
2つの int 値のうち大きいほうを返す。
static double
 min(double a, double b)
2つの double 値のうち小さいほうを返す。
static int
 min(int a, int b)
2つの int 値のうち小さいほうを返す。
static double
 pow(double a, double b)
1 番目の引数を、2 番目の引数で累乗した値を返す。
static double
 random()
0.0 以上で 1.0 より小さい、正の符号の付いた double 値を返す。
static long
 round(double a)
引数にもっとも近い long を返す (引き分けの場合は切り上げる)。
static int
 round(float a)
引数にもっとも近い int を返す (引き分けの場合は切り上げる)。
static double
 sin(double a)
指定された角度の正弦 (サイン) を返す。
static double
 sqrt(double a)
double 値の正しく丸めた正の平方根を返す。
static double
 tan(double a)
指定された角度の正接 (タンジェント) を返す。
static double
 toDegrees(double angrad)
ラジアンで計測した角度を、相当する度に変換する。
static double
 toRadians(double angdeg)
度で計測した角度を、相当するラジアンに変換する。
public class Sample {

	public static void main(String[] args) {
		// Mathクラスのクラス変数の利用 ---------------------------------------
		double e = Math.E;               // 自然対数の底 e
		System.out.println(e);           // 結果: 2.718281828459045

		double pi = Math.PI;             // 円周率π
		System.out.println(pi);          // 結果: 3.141592653589793

		// Mathクラスのクラスメソッドの利用 -----------------------------------
		int abs = Math.abs(-125);        // 絶対値
		System.out.println(abs);         // 結果: 125

		double cbrt = Math.cbrt(0.125);  // 立方根 (cubic root)
		System.out.println(cbrt);        // 結果: 0.5

		double ceil = Math.ceil(2.4);    // 小数点以下を切り上げ
		System.out.println(ceil);        // 結果: 3.0

		double floor = Math.floor(2.4);  // 小数点以下を切り捨て
		System.out.println(floor);       // 結果: 2.0

		long round = Math.round(2.4);    // 小数点以下を四捨五入
		System.out.println(round);       // 結果: 2
		round = Math.round(2.5);         // 小数点以下を四捨五入
		System.out.println(round);       // 結果: 3

		double pow = Math.pow(2.0, 3.0); // 1番目の引数を、2番目の引数で累乗
		System.out.println(pow);         // 結果: 8.0

		int max = Math.max(10, 20);      // 大きいほうを返す。
		System.out.println(max);         // 結果: 20

		int min = Math.min(10, 20);      // 小さいほうを返す。
		System.out.println(min);         // 結果: 10

		double random = Math.random();   // 0.0 以上で 1.0 より小さいランダム値
		System.out.println(random);      // 結果: (毎回ランダムな値)

		double sqrt = Math.sqrt(1.44);   // 平方根 (square root)
		System.out.println(sqrt);        // 結果: 1.2
	}
}

ラッパークラス

  • ラッパークラスは、対応する基本データ型(プリミティブ型)の値をオブジェクトにラップする。
ラッパークラス
ラッパークラス 対応する
基本データ型
Boolean boolean
Byte byte
Character char
Double double
Float float
Integer int
Long long
Long short

クラスの拡張

  • 既に定義されているクラスをもとに、拡張した新しいクラスを定義することを、”クラスの拡張" という。
  • 基になるクラス(厳密には、継承関係が成り立つ場合の継承元クラス)を、"スーパークラス" と呼ぶ。
    ※基底クラス(base class)と呼ぶ場合もあるが、Javaでは、スーパークラス(superclass)と呼ぶのが一般的。
  • 新たに定義された、拡張したクラス(厳密には、継承関係が成り立つ場合の継承先クラス)を、 "サブクラス" と呼ぶ。
    ※派生クラス(derived class)と呼ぶ場合もあるが、Javaでは、サブクラス(subclass)と呼ぶのが一般的。
  • 拡張されたクラス(サブクラス)は、既存のクラス(スーパークラス)のメンバを受け継ぐ。これを、"継承" という。
  • "拡張" と "継承" は意味が異なるので注意。
// スーパークラス
class Ship {
	private int shipNum;
	private double weight;

	// スーパークラスのコンストラクタ
	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

// サブクラス
class Submarine extends Ship {    // Shipクラス(スーパークラス)を拡張して、Submarineクラス(サブクラス)を作成
	private int torpedoNum;

	// サブクラスのコンストラクタ
	public Submarine() {          // 先頭で、スーパークラスのコンストラクタが呼び出される
		torpedoNum = 4;
		System.out.println("潜水艦を用意しました。");
	}

	public void setTorpedoNum(int num) {
		if (num >= 4) {
			torpedoNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getTorpedoNum() {
		return torpedoNum;
	}
}

public class Sample {

	public static void main(String[] args) {
		Submarine submarine;
		submarine = new Submarine();         // サブクラスのオブジェクトを作成

		// スーパークラスから継承したメソッドの呼び出し
		int sn = submarine.getShipNum();
		System.out.println(sn);              // 結果: 1

		// サブクラスのメソッドの呼び出し
		int tn = submarine.getTorpedoNum();
		System.out.println(tn);              // 結果: 4
	}
}

コンストラクタの選択的な呼び出し ※this(), super()

  • this(): 自分自身のオブジェクト参照thisを用いたコンストラクタ呼び出し。
    コンストラクタ内で、同じクラスの、別のコンストラクタを呼び出すことができる。
    引数によって選択的な呼び出しが可能。
  • super(): スーパークラスのオブジェクト参照superを用いたコンストラクタ呼び出し。
    コンストラクタ内で、スーパークラスのコンストラクタを呼び出すことができる。
    引数によって選択的な呼び出しが可能。
    省略した場合は、スーパークラスの引数無しのコンストラクタが呼び出される(引数無しsuper()と同じ)。
  • this(), super() いずれもコンストラクタ内の最初のステートメントに限り、利用できる。→ 同時に利用はできない。
// スーパークラス
class Superclass {

	// 引数無しのコンストラクタ ※オーバーロード
	public Superclass() {
		System.out.println("スーパークラスの、引数無しのコンストラクタ");
	}

	// 引数1つのコンストラクタ ※オーバーロード
	public Superclass(int i) {
		this(); // 同じクラスの、引数無しのコンストラクタをを呼び出す
		System.out.println("スーパークラスの、引数1つのコンストラクタ");
	}

	// 引数2つのコンストラクタ ※オーバーロード
	public Superclass(int i, double db) {
		this(9); // 同じクラスの、引数1つのコンストラクタをを呼び出す
		System.out.println("スーパークラスの、引数2つのコンストラクタ");
	}
}

// サブクラス
class Subclass extends Superclass {

	// 引数無しのコンストラクタ ※オーバーロード
	public Subclass() {
		super(5); // スーパークラスの、引数1つのコンストラクタを呼び出す
		System.out.println("サブクラスの、引数無しのコンストラクタ");
	}

	// 引数1つのコンストラクタ ※オーバーロード
	public Subclass(int i) {
		super(); // スーパークラスの、引数無しのコンストラクタを呼び出す ※明示的
		System.out.println("サブクラスの、引数1つのコンストラクタ");
	}

	// 引数2つのコンストラクタ ※オーバーロード
	public Subclass(int i, double db) {
		// super();を省略した場合、スーパークラスの、引数無しのコンストラクタが呼び出される
		System.out.println("サブクラスの、引数2つのコンストラクタ");
	}
}

public class Sample {

	public static void main(String[] args) {
		Superclass superclass1 = new Superclass();
		System.out.println(); // 改行

		Superclass superclass2 = new Superclass(3);
		System.out.println();

		Superclass superclass3 = new Superclass(3, 2.3);
		System.out.println();

		// ----------------------------------------------------------------
		Subclass subclass1 = new Subclass();
		System.out.println();

		Subclass subclass2 = new Subclass(6);
		System.out.println();

		Subclass subclass3 = new Subclass(6, 1.2);
	}

}

/* 結果:

 スーパークラスの、引数無しのコンストラクタ

 スーパークラスの、引数無しのコンストラクタ
 スーパークラスの、引数1つのコンストラクタ

 スーパークラスの、引数無しのコンストラクタ
 スーパークラスの、引数1つのコンストラクタ
 スーパークラスの、引数2つのコンストラクタ

 スーパークラスの、引数無しのコンストラクタ
 スーパークラスの、引数1つのコンストラクタ
 サブクラスの、引数無しのコンストラクタ

 スーパークラスの、引数無しのコンストラクタ
 サブクラスの、引数1つのコンストラクタ

 スーパークラスの、引数無しのコンストラクタ
 サブクラスの、引数2つのコンストラクタ

 */

メソッドのオーバーライド

  • スーパークラスで定義されたメンバを、サブクラスで再定義し、機能を上書きすること。
  • サブクラスでは、スーパークラスのメソッドと同じ関数名, 引数の型・数のメソッドを定義することができる。
  • クラス間で、同じ名前のメソッドを複数定義し、利用時にプログラムの文脈に応じて選択することで、複数の動作を行わせる事ができる。多態性を実現する一つの手段。
    ※ 多態性(ポリモーフィズム)とは、プログラミング言語の型システムの性質を表すもので、プログラミング言語の各要素(定数、変数、式、オブジェクト、関数、メソッドなど)についてそれらが複数の型に属することを許すという性質を指す。
// スーパークラス
class Superclass {
	public void show() {
		System.out.println("スーパークラスのメソッド");
	}
}

// サブクラス
class Subclass extends Superclass {

	// メソッドのオーバーライド
	public void show() {
		System.out.println("サブクラスのメソッド");
	}

	public void showSub() {
		System.out.println("サブクラス独自のメソッド");
	}
}

public class Sample {

	public static void main(String[] args) {
		// ----------------------------------------------------------------------------------------------------
		// サブクラス型の変数に、サブクラスのオブジェクトを代入
		Subclass subclass;
		subclass = new Subclass();

		subclass.show();        // 結果: サブクラスのメソッド ※サブクラスでオーバーライドしたメソッド呼び出し
		subclass.showSub();     // 結果: サブクラス独自のメソッド

		// ----------------------------------------------------------------------------------------------------
		// スーパークラス型の変数に、スーパークラスのオブジェクトを代入
		Superclass superclass1;
		superclass1 = new Superclass();

		superclass1.show();     // 結果: スーパークラスのメソッド

		// ----------------------------------------------------------------------------------------------------
		// スーパークラス型の変数に、サブクラスのオブジェクトを代入
		Superclass superclass2;
		superclass2 = new Subclass();

		superclass2.show();     // 結果: サブクラスのメソッド ※サブクラスでオーバーライドしたメソッド呼び出し
		// superclass2.showSub(); ← ERROR

		// ----------------------------------------------------------------------------------------------------
		// スーパークラス型の配列変数の要素に、スーパークラスやサブクラスのオブジェクトを代入
		Superclass[] superclass3;
		superclass3 = new Superclass[3];

		superclass3[0] = new Superclass();
		superclass3[1] = new Subclass();
		superclass3[2] = new Superclass();

		// オブジェクトのクラスに応じたshow()メソッドが呼び出される ※多態性の機能
		superclass3[0].show();  // 結果: スーパークラスのメソッド
		superclass3[1].show();  // 結果: サブクラスのメソッド ※サブクラスでオーバーライドしたメソッド呼び出し
		superclass3[2].show();  // 結果: スーパークラスのメソッド
	}

}

フィールド・メソッドへの選択的なアクセス ※this, super

  • this: 自分自身のオブジェクト参照。同じクラスの、フィールド・メソッドへアクセスできる。
    メソッドにおいて、ローカル変数とフィールド名が重複する場合に、フィールドを選択してアクセスできる。
  • super: スーパークラスのオブジェクト参照。スーパークラスの、フィールド・メソッドへアクセスできる。
    スーパークラスとサブクラスにおいて、フィールド・メソッド名がそれぞれ重複する場合に、スーパークラスを選択してアクセスできる。
// スーパークラス
class Superclass {
	protected int num;

	public void show() {
		System.out.println("スーパークラスのメソッド");
	}
}

// サブクラス
class Subclass extends Superclass {
	private int num;               // スーパークラスと同じ名前のフィールド

	// スーパークラスと同じ名前のメソッド ※オーバーライド
	public void show() {
		System.out.println("サブクラスのメソッド");
	}

	// ----------------------------------------------------------------------------------------
	public void setNum(int num) {  // フィールドと同じ名前のローカル変数
		this.num = num;            // 同じクラスのフィールドnumに、ローカル変数numを代入
	}

	public int getNum() {
		return num;                // 同じクラスのフィールドnumを返す
	}

	// ----------------------------------------------------------------------------------------
	public void setSuperNum(int num) {
		super.num = num;           // スーパークラスのフィールドnumに、ローカル変数numを代入
	}

	public int getSuperNum() {
		return super.num;          // スーパークラスのフィールドnumを返す
	}

	// ----------------------------------------------------------------------------------------
	public void showSuper() {
		super.show();              // スーパークラスのshow()メソッドを呼び出す
	}

	public void showSub() {
		this.show();               // 同じクラスのshow()メソッドを呼び出す ※thisは省略可能
	}
}

public class Sample {

	public static void main(String[] args) {
		Subclass subclass = new Subclass();

		subclass.setNum(753);
		int res = subclass.getNum();
		System.out.println(res);       // 結果: 753

		subclass.setSuperNum(123);
		res = subclass.getSuperNum();
		System.out.println(res);       // 結果: 123

		subclass.show();               // 結果: サブクラスのメソッド
		subclass.showSuper();          // 結果: スーパークラスのメソッド
		subclass.showSub();            // 結果: サブクラスのメソッド
	}

}

final修飾子

  • フィールドまたはローカル変数にfinal修飾子を用いると、値を変更できない。→ 定数となる。
    ※値が設定されていない、final修飾子があるフィールドを、コンストラクタで初期化することは可能。
  • メソッドにfinal修飾子を用いると、サブクラスでオーバーライドできない。
  • クラスにfinal修飾子を用いると、サブクラスに拡張ができない。
  • あるクラス内の、static final 変数は、インスタンス毎ではなく、そのクラスにひとつの定数となる。
    → 複数のインスタンス化をする場合に、メモリー使用量を抑えることができる。
// final修飾子があるクラス
final class Ship {
 
    // final修飾子があるフィールド
    private final int shipNum;
 
    private double weight;
 
    public Ship() {
        shipNum = 1;                           // ※ final修飾子があるフィールドは、コンストラクタでは初期化できる
        // shipNum = 3;                           ※ 代入はできない
        weight = 1.0;
        System.out.println("船を用意しました。");
    }
 
    // final修飾子があるメソッド
    public final void setShipNum(int num) {
        if (num >= 1) {
            // shipNum = num;                     ※ final修飾子があるフィールドは、値が変更できない
            // System.out.println("適切な値" + num + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }
 
    public void setWeight(double wt) {
        if (wt >= 0) {
            weight = wt;
            System.out.println("適切な値" + wt + "が設定されました。");
        } else {
            System.out.println("適切な値ではありません。");
        }
    }
 
    public int getShipNum() {
        return shipNum;
    }
 
    public double getWeight() {
        return weight;
    }
 
    public void go() {
        System.out.println("進みます");
    }
}
 
/*
 * class Submarine extends Ship {                 ※ final修飾子があるクラスは、拡張できない
 *      private int torpedoNum;
 *
 *      public Submarine() {
 *          torpedoNum = 4;
 *      System.out.println("潜水艦を用意しました。");
 *      }
 *
 *      public void setTorpedoNum(int num) {
 *          if (num >= 4) {
 *              torpedoNum = num;
 *              System.out.println("適切な値" + num + "が設定されました。");
 *          } else {
 *              System.out.println("適切な値ではありません。");
 *          }
 *      }
 *
 *      public int getTorpedoNum() {
 *          return torpedoNum;
 *      }
 *
 *      public void setShipNum(int num) {         ※ final修飾子があるメソッドは、オーバーライドできない
 *          ;
 *      }
 * }
 */
 
public class Sample {
 
    public static void main(String[] args) {
        // final修飾子があるローカル変数 (→ 定数)
        final int NUM = 25;
        // NUM = 35;                              ※ final修飾子があるローカル変数は、値が変更できない。(→ 定数)
 
        Ship ship = new Ship();
        System.out.println(ship.getShipNum());    // 結果: 1
    }
}

抽象クラス

  • 抽象クラス: abstract修飾子があるクラス。
  • 抽象クラスは、オブジェクトが作成できない。
  • 抽象クラスは、抽象メソッドを持つことができる。※無くてもいいのだが、普通は抽象メソッドを持つ。
  • 抽象メソッド: 処理内容が定義されていないメソッド。abstract修飾子がある。
  • 抽象クラスから継承した抽象メソッドの処理内容は、サブクラスで定義(オーバーライド)しなければならない。
  • 抽象クラスは、オブジェクトが作成できないが、そのクラス型の変数や配列は作成できる。そして、サブクラスのオブジェクトを指すことができる。
    → 抽象クラスが抽象メソッドを持つ場合、サブクラスは必ずオーバーライドしたメソッド(同じ関数名, 引数の型・数のメソッド)を持っているため、多態性が利用できる。
  • instanceof演算子を利用して、オブジェクトのクラスを調べることができる。
// 抽象クラス
abstract class Ship { // 別パッケージで宣言・定義する場合、先頭にさらにpublic修飾子を付ける
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}

	// 抽象メソッド
	abstract void abstractShow();
}

// サブクラス
class Submarine extends Ship {          // 抽象クラスShipを拡張する
	private int torpedoNum;

	public Submarine() {
		torpedoNum = 4;
		System.out.println("潜水艦を用意しました。");
	}

	public void setTorpedoNum(int num) {
		if (num >= 4) {
			torpedoNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getTorpedoNum() {
		return torpedoNum;
	}

	// 抽象メソッドのオーバーライド
	@Override                           // アノテーション(注釈) ※書かなくても良い
	void abstractShow() {
		System.out.println("Submarineクラスで、抽象メソッドをオーバーライド");
	}

}

// サブクラス
class Battleship extends Ship {         // 抽象クラスShipを拡張する
	private int missileNum;

	public Battleship() {
		missileNum = 3;
		System.out.println("戦艦を用意しました。");
	}

	public void setMissileNum(int num) {
		if (num >= 4) {
			missileNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getMissileNum() {
		return missileNum;
	}

	// 抽象メソッドのオーバーライド
	@Override
	void abstractShow() {
		System.out.println("Battleshipクラスで、抽象メソッドをオーバーライド");
	}

}

public class Sample {

	public static void main(String[] args) {
		// Ship ship = new Ship(); 抽象クラスのオブジェクトは作成できない

		Ship[] ship = new Ship[3];                       // 抽象クラスの変数・配列は作成できる

		// 配列要素が、サブクラスのオブジェクトを指すようにする
		ship[0] = new Submarine();
		ship[1] = new Battleship();
		ship[2] = new Submarine();

		// 多態性
		ship[0].abstractShow();                          // 結果: Submarineクラスで、抽象メソッドをオーバーライド
		ship[1].abstractShow();                          // 結果: Battleshipクラスで、抽象メソッドをオーバーライド
		ship[2].abstractShow();                          // 結果: Submarineクラスで、抽象メソッドをオーバーライド

		// (1) クラスを調べる
		for (int i = 0; i < ship.length; i++) {
			if (ship[i] instanceof Battleship) {         // 左辺の変数が、右辺のクラスのインスタンスを指しているか調べる
				System.out.println((i + 1) + "番目はBattleshipクラス");
			} else {
				System.out.println((i + 1) + "番目はSubmarineクラス");
			}
		}

		// (2) クラスを調べる
		Class[] checkclass = new Class[3];
		for (int i = 0; i < ship.length; i++) {
			checkclass[i] = ship[i].getClass();
			System.out.println((i + 1) + "番目は" + checkclass[i]);
		}

		// ---------------------------------------------------------------------------------------------
		// 抽象クラス(スーパークラス)の変数からは、サブクラス独自のメソッドは扱えない
		// ship[0].getTorpedoNum();

		Submarine submarine = new Submarine();
		submarine.abstractShow();                        // 結果: Submarineクラスで、抽象メソッドをオーバーライド
		System.out.println(submarine.getTorpedoNum());   // 結果: 4

		Battleship battleship = new Battleship();
		battleship.abstractShow();                       // 結果: Battleshipクラスで、抽象メソッドをオーバーライド
		System.out.println(battleship.getMissileNum());  // 結果: 3
	}
}

インタフェース

  • インタフェース: 特定の機能(具象メソッド ※java SE 8から)や、その概要(抽象メソッド)、特定のデータ(定数フィールド)を纏めたもの。同一のインタフェースを実装したクラス間では、それらを共通に持つことになる。→ 沢山のクラスを扱う場合において、多態性を利用して纏めて扱えることや、機能やデータの共通化ができる。
  • インタフェースのアクセス修飾子は、無指定 public とする。
  • インタフェースは、フィールド(staticな定数)メソッド(抽象メソッドや具象メソッド)をメンバとすることができる。
  • インタフェースは、クラス・インタフェースをネストできる。
  • インタフェースのフィールドに修飾子が無い場合は、public static final であることと同じ。→  定数となる。
  • インタフェースのメソッドに修飾子が無い場合は、public abstract であることと同じ。→  抽象メソッドとなる。
  • Java SE 8 からは、defaultキーワードを用いることで、メソッドの実装(処理内容の定義)が可能になった。これをデフォルトメソッドと呼ぶ。
  • クラスに、インタフェースを実装することができる。
  • Javaでは、複数のクラスからの多重継承はできないが、複数のインタフェースからの多重継承は可能。
  • インタフェースはextendsを用いて拡張することができる。このとき、基になるインタフェースをスーパーインタフェース、拡張したものをサブインタフェースと呼ぶ。
// インタフェース
interface Vehicle {           // Java SE 8 からはメソッドの実装(処理内容の定義)も可能
	// 定数
	int PASSENGERNUM = 50;    // public static finally

	// 抽象メソッド
	void getOn();             // public abstract

	void getOff();            // public abstract
}

// インタフェースを実装したクラス
class Plane implements Vehicle {
	@Override
	public void getOn() {
		System.out.println("飛行機に乗る。");
	}

	@Override
	public void getOff() {
		System.out.println("飛行機を降りる。");
	}
}

// インタフェースを実装したクラス
class Ship implements Vehicle {
	@Override
	public void getOn() {
		System.out.println("船に乗る。");
	}

	@Override
	public void getOff() {
		System.out.println("船を降りる。");
	}
}

public class Sample {

	public static void main(String[] args) {
		int passengerNum = Plane.PASSENGERNUM + Ship.PASSENGERNUM;  // 定数の利用  ※staticなのでいつでも利用できる
		System.out.println("飛行機と船を併せた収容可能な人数は、" + passengerNum + "人です。");

		Plane plane = new Plane();
		plane.getOn();
		plane.getOff();

		Ship ship = new Ship();
		ship.getOn();
		ship.getOff();

		// ----------------------------------------------------------------------------------------------
		Vehicle[] vehicle = new Vehicle[3];                         // インタフェース型の配列
		vehicle[0] = new Plane();
		vehicle[1] = new Ship();
		vehicle[2] = new Plane();

		for (int i = 0; i < vehicle.length; i++) {
			// 多態性
			vehicle[i].getOn();
			vehicle[i].getOff();
		}
	}

}
// インタフェース
interface Vehicle {                         // Java SE 8 からはメソッドの実装(処理内容の定義)も可能
	// 定数
	int PASSENGERNUM = 2;                   // public static finally

	// 抽象メソッド
	void getOn();                           // public abstract

	void getOff();                          // public abstract
}

// インタフェース ※スーパーインタフェース
interface LockOnAttack {
	void fireMissile();
}

// インタフェース ※サブインタフェース(スーパーインタフェースは複数でも可)
interface Attack extends LockOnAttack {
	void fireGatlingGun();
}

// 複数のインタフェースを実装したクラス
class Fighter implements Vehicle, Attack {  // インタフェースは、多重継承が可能
	@Override
	public void getOn() {
		System.out.println("戦闘機に乗る。");
	}

	@Override
	public void getOff() {
		System.out.println("戦闘機を降りる。");
	}

	@Override
	public void fireMissile() {
		System.out.println("ミサイル攻撃する。");
	}

	@Override
	public void fireGatlingGun() {
		System.out.println("ガトリング攻撃する。");
	}
}

public class Sample {

	public static void main(String[] args) {
		int passengerNum = Fighter.PASSENGERNUM;     // 定数の利用 ※staticなのでいつでも利用できる
		System.out.println("この戦闘機に搭乗可能な人数は、" + passengerNum + "人です。");

		Fighter fighter = new Fighter();
		fighter.getOn();
		fighter.fireMissile();
		fighter.fireGatlingGun();
		fighter.getOff();
	}

}

クラス・インタフェースのネスト

  • クラスは、クラス・インタフェースをネストすることができる。
  • インタフェースは、クラス・インタフェースをネストすることができる。
  • エンクロージング型: ネストした型(クラス・インタフェース)を囲む型(クラス・インタフェース)
クラス・インタフェースのネスト
ネストしたクラス・インタフェース
static インタフェース (暗黙的にstatic)
staticな メンバクラス
非static
※内部クラス(インナークラスとも呼ぶ)
非staticな メンバクラス
無名内部クラス
(無名クラスや匿名クラスとも呼ぶ)
ローカル内部クラス
(コンストラクタやメソッド内で宣言)

パッケージ

  • パッケージ: 名前空間の中にあるクラス・インタフェースをまとめるメカニズム。パッケージを用いることで、名前が同じクラス・インタフェースを作ることができる。
  • サブパッケージ: パッケージの下の階層につくるパッケージであり、パッケージをわかりやすく分類できる。
    パッケージ名をドット(.)で区切り、パッケージ宣言する。
  • パッケージ宣言では、パッケージ名を指定する。
  • パッケージ宣言をすると、そのファイル内で宣言された全てのクラス・インタフェースが、そのパッケージに含まれる。
  • パッケージ宣言をしない場合、そのファイル内で宣言された全てのクラス・インタフェースは、デフォルトパッケージに含まれる。
  • 異なるファイルのクラス・インタフェースを、同じパッケージにしたり、異なるパッケージにすることができる。
  • 同じファイルのクラス・インタフェースを、異なるパッケージにすることはできない。
  • 異なるパッケージの場合は、クラス・インタフェース名にパッケージ名を付ける
  • 同じパッケージの場合は、クラス・インタフェース名にパッケージ名を付けなくても良い (付けても良い)
  • クラス・インタフェースにアクセス修飾子publicがある場合、同じパッケージと異なるパッケージから利用できる。
  • クラス・インタフェースにアクセス修飾子が無い場合、同じパッケージからのみ利用できる。

< pAディレクトリ内 Ship.java >

// pAディレクトリ内 Ship.java

// パッケージ宣言
package pA;                 // このファイル内のクラス・インタフェースを、pAパッケージに含む

// pAパッケージに含まれる
public class Ship {         // 別パッケージで利用するには public にする
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

< pBディレクトリ内 Sample.java >

// pBディレクトリ内 Sample.java

// パッケージ宣言
package pB;                          // このファイル内のクラス・インタフェースを、pBパッケージに含む

// pBパッケージに含まれる
class Submarine extends pA.Ship {    // 別パッケージの、publicなクラスを拡張
	private int torpedoNum;

	public Submarine() {
		torpedoNum = 4;
		System.out.println("潜水艦を用意しました。");
	}

	public void setTorpedoNum(int num) {
		if (num >= 4) {
			torpedoNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getTorpedoNum() {
		return torpedoNum;
	}
}

// pBパッケージに含まれる
public class Sample {

	public static void main(String[] args) {
		// pAパッケージ(異なるパッケージ)の、Shipクラス(スーパークラス)の利用
		// 異なるパッケージの場合は、クラス名にパッケージ名を付ける
		pA.Ship ship = new pA.Ship();
		System.out.println(ship.getShipNum());       // 結果: 1

		// pBパッケージ(同じパッケージ)の、Submarineクラス(サブクラス)の利用
		// 同じパッケージの場合は、クラス名にパッケージ名を付けなくても良い (付けても良い)
		Submarine submarine = new Submarine();       
		System.out.println(submarine.getShipNum());  // 結果: 1
	}

}

インポート

  • 異なるパッケージのクラス・インタフェースを利用する場合、クラス・インタフェース名にパッケージ名をつけて利用する。
    このとき、インポート宣言をすると、パッケージ名を省き、クラス・インタフェース名だけで利用できる。
  • インポート宣言では、クラス・インタフェース名を指定する。
  • クラスライブラリのjava.langパッケージは、インポート宣言をしなくても、クラス名だけで利用できる。
    ※java.langパッケージにはStringクラスも含まれている。
  • インポート宣言には、"単一型インポート宣言" と "オンデマンド型インポート宣言" がある。
  • 単一型インポート宣言: 1つのクラス・インタフェースをインポートする。
  • オンデマンド型インポート宣言: 同じパッケージに含まれる複数のクラス・インタフェースを全てインポートする。*(アスタリスク)を使用する。
    ※サブパッケージのクラス・インタフェースもインポートする場合は、別途インポート宣言する。

< pAディレクトリ内 Ship.java >

// pAディレクトリ内 Ship.java

// パッケージ宣言
package pA;                 // このファイル内のクラス・インタフェースを、pAパッケージに含む

// pAパッケージに含まれる
public class Ship {         // 別パッケージで利用するには public にする
	private int shipNum;
	private double weight;

	public Ship() {
		shipNum = 1;
		weight = 1.0;
		System.out.println("船を用意しました。");
	}

	public void setShipNum(int num) {
		if (num >= 1) {
			shipNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public void setWeight(double wt) {
		if (wt >= 0) {
			weight = wt;
			System.out.println("適切な値" + wt + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getShipNum() {
		return shipNum;
	}

	public double getWeight() {
		return weight;
	}

	public void go() {
		System.out.println("進みます");
	}
}

< pBディレクトリ内 Sample.java >

// pBディレクトリ内 Sample.java

// パッケージ宣言
package pB;                          // このファイル内のクラス・インタフェースを、pBパッケージに含む

// インポート宣言
import pA.Ship;                      // 別パッケージのクラスをインポートする ※パッケージ名を省略できるようになる

// pBパッケージに含まれる
class Submarine extends pA.Ship {    // 別パッケージの、publicなクラスを拡張
	private int torpedoNum;

	public Submarine() {
		torpedoNum = 4;
		System.out.println("潜水艦を用意しました。");
	}

	public void setTorpedoNum(int num) {
		if (num >= 4) {
			torpedoNum = num;
			System.out.println("適切な値" + num + "が設定されました。");
		} else {
			System.out.println("適切な値ではありません。");
		}
	}

	public int getTorpedoNum() {
		return torpedoNum;
	}
}

// pBパッケージに含まれる
public class Sample {

	public static void main(String[] args) {
		// pAパッケージ(異なるパッケージ)の、Shipクラス(スーパークラス)の利用
		// 異なるパッケージの場合は、基本的に、クラス名にパッケージ名を付けるのだが、
		// pA.Shipをインポートしているので、パッケージ名を省略できる
		Ship ship = new Ship();
		System.out.println(ship.getShipNum());       // 結果: 1

		// pBパッケージ(同じパッケージ)の、Submarineクラス(サブクラス)の利用
		// 同じパッケージの場合は、クラス名にパッケージ名を付けなくても良い (付けても良い)
		Submarine submarine = new Submarine();
		System.out.println(submarine.getShipNum());  // 結果: 1
	}

}

例外

  • 例外処理: プログラムがある処理を実行中に、なんらかの異常が発生した場合に、現在の処理を中断(中止)して、別の処理を行うこと。その際に発生した異常のことを "例外" と呼ぶ。
  • 例外が生じるメソッドでの例外処理は、次の2通りの方法がある。
    (1) try, catch, finally等を利用して、そのメソッド内で例外処理する。
    (2) スロー宣言(throws宣言)、場合によってはthrow文も併せて利用して、そのメソッドの呼び出し元に例外処理をまかせる。
  • tryブロック(try節): 例外が発生する可能性のある処理を記述する。
  • catchブロック(catch節): 例外ハンドラとも呼ばれる。例外を受け取り、それに対処する処理を記述する。
    catchブロックでは、tryブロックで送出された例外の型が、引数の型と同じであれば例外を受け取り、例外に対する処理をする。
    ブロック内の処理が終わると、それ以降の処理が継続される。
  • finallyブロック(finally節): 例外が発生してもしなくても必ず行う処理を記述する。
  • < 例外の流れ >
    (1) tryブロックで例外が発生すると、そこで処理を中断し、catchブロックに処理が移る。

    (2) もしも処理中のメソッドでcatchブロックが見つからない場合、呼び出し元で探される。
    ※finallyブロックがある場合は、その処理を行ってから、呼び出し元で探される。

    (3) ルート(mainメソッド)まで戻ってもcatchブロック(とfinallyブロック)が見つからない場合は、基本的にプログラムは強制終了されるが、これは深刻・致命的な異常を招くおそれがある。
    ※RuntimeExceptionのサブクラスの例外処理(catchブロックやfinallyブロックの記述)は任意だが、できるだけ対応する処理をするほうが良い。
  • catchブロックで受け取る例外の型は基本的にjava.langパッケージのThrowableクラスのサブクラスとなる。
    ※Errorクラスの例外処理はしないので、Throwableクラスを直接受け取ることも無い。
  • Throwableクラス(ルート)からは、Errorクラス(実行不能エラー)と、Exceptionクラスが拡張されている。
    ※Errorクラスは通常例外処理しない。Exceptionクラスやそのサブクラスは例外処理をする。(RuntimeExceptionのサブクラスは例外処理しなくてもいい。)
  • Exceptionクラスからは、IOExcepitonや、RuntimeExceptionなどが拡張されている。

< 例1: 例外処理を、そのメソッド内で対処する(スロー宣言を利用しない場合) >

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		System.out.println("円の半径を入力してください。");
		String str;

		try {                     // ■tryブロック ※例外が発生すると処理を中断し、catchブロックへ処理を移す
			str = br.readLine();                           // 例外が発生する可能性がある
			int radius = Integer.parseInt(str);            // 例外が発生する可能性がある
			double area = radius * radius * Math.PI;
			System.out.println("半径" + radius + "cmの円の面積は、" + area + "cm^2 です。");
		} catch (IOException e) { // ■catchブロック(例外ハンドラ) ※複数の例外がある場合は、例外の型に応じて複数記述する
			e.printStackTrace();                           // 標準エラーストリームに出力
			System.out.println("入出力例外" + e + "が送出されました。");
		} catch (NumberFormatException e) { // ■catchブロック
			e.printStackTrace();                           // 標準エラーストリームに出力
			System.out.println("文字列を数値型に変換する際、文字列の形式が正しくない例外" + e + "が送出されました。");
		} finally {               // ■finallyブロック ※任意のブロック。例外が発生してもしなくても必ず行う処理を記述する
			try {
				br.close();                                // ストリームを閉じる
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("入出力例外" + e + "が送出されました。");
			}
		}
	}
}

< 例2: 例外処理を、そのメソッドの呼び出し元にスローする(スロー宣言を利用する場合) >

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) {
		Sample sample = new Sample();

		try {
			sample.calcAreaOfCircle();                     // 例外が発生する可能性がある
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("入出力例外" + e + "が送出されました。");
		}
	}

	public void calcAreaOfCircle() throws IOException { // スロー宣言 ※この例ではfinallyブロック内での例外を呼び出し元にスロー
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		System.out.println("円の半径を入力してください。");
		String str;

		try {                     // ■tryブロック ※例外が発生すると処理を中断し、catchブロックへ処理を移す
			str = br.readLine();                           // 例外が発生する可能性がある
			int radius = Integer.parseInt(str);            // 例外が発生する可能性がある
			double area = radius * radius * Math.PI;
			System.out.println("半径" + radius + "cmの円の面積は、" + area + "cm^2 です。");
		} catch (IOException e) { // ■catchブロック(例外ハンドラ) ※複数の例外がある場合は、例外の型に応じて複数記述する
			e.printStackTrace();                           // 標準エラーストリームに出力
			System.out.println("入出力例外" + e + "が送出されました。");
		} catch (NumberFormatException e) { // ■catchブロック
			e.printStackTrace();                           // 標準エラーストリームに出力
			System.out.println("文字列を数値型に変換する際、文字列の形式が正しくない例外" + e + "が送出されました。");
		} finally {               // ■finallyブロック ※任意のブロック。例外が発生してもしなくても必ず行う処理を記述する
			br.close();                                    // ストリームを閉じる
		}
	}
}

例外のクラス

  • 例外のクラスをつくることができる。これは、Throwableクラスのサブクラスである必要がある。
    ※通常は、ThrowableクラスのサブクラスであるExceptionクラス、またはそのサブクラスを拡張する。
  • 例外が生じる可能性があるメソッドに、スロー宣言をすることで、呼び出したメソッドに例外をスローできる。
  • throw文で、例外をスローできる。スローする例外は、Throwableクラスのサブクラスである必要がある。
    ※通常は、ThrowableクラスのサブクラスであるExceptionクラス、またはそのサブクラス。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// 自作の例外のクラス ※Exceptionクラスまたはそのサブクラスを拡張する
class MyException extends Exception {
	public void showError() {
		System.out.println("未入力の例外です");
	}
}

public class Sample {

	public static void main(String[] args) {
		Sample sample = new Sample();

		try {
			sample.setName();             // 例外が発生する可能性がある
		} catch (IOException e) {
			e.printStackTrace();          // 標準エラーストリームに出力
			System.out.println("入出力例外" + e + "が送出されました。");
		} catch (MyException e) {         // 自作の例外に対する例外処理
			e.printStackTrace();
			e.showError();
		}
	}

	// 例外が生じた場合に、例外をスローするメソッド
	public void setName() throws MyException, IOException { // 例外が複数の場合、スロー宣言にコンマ(,)で区切って記述する
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		System.out.println("名前を入力してください。");
		String str = null;

		try {
			str = br.readLine(); // 例外(IOException)が発生する可能性がある。例外処理はsetName()を呼び出したメソッドにまかせる
		} finally {
			br.close();          // 例外(IOException)が発生する可能性がある。例外処理はsetName()を呼び出したメソッドにまかせる
		}

		if (str.equals("")) {
			MyException e = new MyException();   // 自作の例外クラスのオブジェクト
			throw e;                             // throw文で、未入力時に自作の例外をスローする
		} else {
			System.out.println("名前" + str + "が入力されました。");
		}
	}
}

ストリーム

  • < java.langパッケージ >
    • Systemクラス
    • System.in: 標準入力ストリーム。
    • System.out: 標準出力ストリーム。
  • < java.ioパッケージ >
    • java.ioパッケージ: データストリーム、直列化、およびファイルシステム経由でのシステム入出力用に提供されている。
    • BufferedReaderクラス: 文字、配列、行をバッファリングすることによって、文字型入力ストリームからテキストを効率良く読み込む。
    • FileReaderクラス: 文字ファイルを読み込むための簡易クラス。
    • FileWriterクラス: 文字ファイルを書き込むための簡易クラス。
    • BufferedWriterクラス: 文字をバッファリングすることによって、文字、配列、または文字列を効率良く文字型出力ストリームに書き込む。
    • InputStreamReaderクラス: バイトストリームから文字ストリームへの橋渡しの役目を持つ。バイトを読み込み、指定された charset を使用して文字にデコードする。
    • PrintWriterクラス: オブジェクトの書式付き表現をテキスト出力ストリームに出力する。

< 標準入出力 >

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Sample {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // System.in : 標準入力
		System.out.println("名前を入力してください。");                           // System.out : 標準出力
		String name;

		try {
			name = br.readLine();                                                 // テキスト行 読み込み
			System.out.println("こんにちは" + name + "さん。");
		} catch (IOException e) {
			e.printStackTrace();                                                  // 標準エラーストリームに出力
			System.out.println("入出力例外" + e + "が送出されました。");
		} finally {
			try {
				br.close();                                                       // ストリームを閉じる
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("入出力例外" + e + "が送出されました。");
			}
		}
	}
}

< ファイル入力 >

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Sample {

	public static void main(String[] args) {
		BufferedReader br = null;

		try {
			br = new BufferedReader(new FileReader("mytext.txt")); // バッファリングされた文字型入力ストリームを作成
			String str = null;
			while ((str = br.readLine()) != null) {                // テキスト行 読み込み
				System.out.println(str);                           // テキスト行 出力
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("例外" + e + "が送出されました。");
			System.out.println("ファイル読み込みができませんでした。");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("入出力例外" + e + "が送出されました。");
		} catch (Exception e) {                                    // その他の例外処理 (任意)
			e.printStackTrace();
			System.out.println("例外" + e + "が送出されました。");
		} finally {
			if (br != null) {
				try {
					br.close();                                    // ストリームを閉じる
				} catch (IOException e) {
					e.printStackTrace();
					System.out.println("入出力例外" + e + "が送出されました。");
				}
			}
		}
	}
}

< ファイル出力 >

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Sample {

	public static void main(String[] args) {
		PrintWriter pw = null;
		BufferedReader br = null;

		try {
			// バッファリングされた文字型入力ストリームを作成
			pw = new PrintWriter(new BufferedWriter(new FileWriter("mytext.txt")));

			br = new BufferedReader(new InputStreamReader(System.in));
			String str = null;

			System.out.println("文字列を入力してください。未入力で終了します。");
			while (!(str = br.readLine()).equals("")){
				pw.println(str);                                                         // テキスト行 出力
				System.out.println("文字列を入力してください。未入力で終了します。");
			}

		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("入出力例外" + e + "が送出されました。");
		} catch (Exception e) {                                                          // その他の例外処理 (任意)
			e.printStackTrace();
			System.out.println("例外" + e + "が送出されました。");
		} finally {
			if (br != null) {
				try {
					br.close();                                                          // ストリームを閉じる
				} catch (IOException e) {
					e.printStackTrace();
					System.out.println("入出力例外" + e + "が送出されました。");
				}
			}
			if (pw != null) {
				pw.close();                                                              // ストリームを閉じる
			}
		}
	}

}

スレッド

  • スレッド: プログラム内での実行スレッドのこと。Java仮想マシンでは、アプリケーションは並列に実行される複数のスレッドを使用することができる。
  • < 新しい実行のスレッドを作成するには 2通りの方法がある。 >
    • (1) java.langパッケージのThreadクラスを拡張し、サブクラスとして宣言する。このサブクラスは、Threadクラスの run()メソッド をオーバーライドしなければならない。Threadクラスから継承したstart()メソッドを呼び出すと、スレッドが起動し、run()メソッド内の処理が行われる。
    • (2) Runnable インタフェースを実装するクラスを宣言する。そのクラスは、run()メソッドを実装する。クラスのインスタンスが割り当てられ、Thread の作成時に引数として渡され、開始される。
      ※Threadクラスを拡張しようとするクラスが、他のクラスを拡張する必要がある場合に、特に有効。Javaでは、複数のクラスからの多重継承はできないため。
  • < Threadクラスの主なメソッド >
    • sleep(long millis)メソッド: システムタイマーとスケジューラが正確であることを前提として、現在実行中のスレッドを、指定されたミリ秒数の間、スリープ (一時的に実行を停止) させる。
    • join()メソッド: このスレッドが終了するのを待機する。
  • マルチスレッドで共有データにアクセスする場合、その順番によっては整合性が取れなくなる可能性がある。これを防ぐために、複数のスレッド間で処理のタイミングを取ることを、スレッドの同期という。
  • synchronized修飾子を用いて、スレッドの同期をとることで、別スレッドの割り込みを防ぐ。
    synchronized修飾子 : あるスレッドがメソッド呼び出し中は、別のスレッドからは呼び出せない。

<スレッドを作成する方法(1) : Threadクラスを拡張し、サブクラスとして宣言 >

// Threadクラスを拡張したサブクラス
class Test1 extends Thread {
	@Override
	public void run() {                         // Threadクラスのrunメソッドをオーバーライドしなければならない
		for (int i = 0; i < 10; i++) {
			System.out.println("Test1クラスのスレッドの処理中です。");
		}
	}
}

// Threadクラスを拡張したサブクラス
class Test2 extends Thread {
	@Override
	public void run() {                         // Threadクラスのrunメソッドをオーバーライドしなければならない
		for (int i = 0; i < 10; i++) {
			try {
				// Threadクラスのクラスメソッド
				sleep(1);                       // 指定ミリ秒間だけ一時停止 ※例では1ミリ秒間、一時停止
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("例外" + e + "が送出されました。");
			}
			System.out.println("Test2クラスのスレッドの処理中です。");
		}
	}
}

public class Sample {

	public static void main(String[] args) {
		Test1 test1 = new Test1();
		test1.start();                          // startメソッドを呼び出すと、スレッドが起動 ※処理の流れが2つになる

		Test2 test2 = new Test2();
		test2.start();                          // startメソッドを呼び出すと、スレッドが起動 ※処理の流れが3つになる

		try {
			test2.join();                       // このスレッド(test2のスレッド)が終了するのを待機する
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.out.println("例外" + e + "が送出されました。");
		}

		for (int i = 0; i < 10; i++) {
			try {
				// Threadクラスのクラスメソッド
				Thread.sleep(10);               // 10ミリ秒間、一時停止
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("mainメソッドの処理中です。");
		}
	}
}

<スレッドを作成する方法(2) : Runnableインタフェースを実装するクラスを宣言 >

// Runnableインタフェースを実装したクラス
class Test1 implements Runnable {
    @Override
    public void run() {                         // Runnableインタフェースのrunメソッドをオーバーライドしなければならない
        for (int i = 0; i < 10; i++) {
            System.out.println("Test1クラスのスレッドの処理中です。");
        }
    }
}

//Runnableインタフェースを実装したクラス ※クラスの拡張も可能
class Test2 extends Test3 implements Runnable {
    @Override
    public void run() {                         // Runnableインタフェースのrunメソッドをオーバーライドしなければならない
        for (int i = 0; i < 10; i++) {
            try {
                // Threadクラスのクラスメソッド
                Thread.sleep(1);                // 指定ミリ秒間だけ一時停止 ※例では1ミリ秒間、一時停止
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("例外" + e + "が送出されました。");
            }
            System.out.println("Test2クラスのスレッドの処理中です。");
        }
    }
}

class Test3 {
    public void show(){
        System.out.println("Test3クラスのメソッドです。");
    }
}

public class Sample {

    public static void main(String[] args) {
        Test1 test1 = new Test1();              // Runnableインタフェースを実装したクラスのオブジェクトを作成
        Thread th1 = new Thread(test1);         // Threadクラスのオブジェクトを作成
        th1.start();                            // startメソッドを呼び出すと、スレッドが起動 ※処理の流れが2つになる

        Test2 test2 = new Test2();              // Runnableインタフェースを実装したクラスのオブジェクトを作成
        Thread th2 = new Thread(test2);         // Threadクラスのオブジェクトを作成
        th2.start();                            // startメソッドを呼び出すと、スレッドが起動 ※処理の流れが3つになる

        try {
            th2.join();                         // このスレッド(th2のスレッド)が終了するのを待機する
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("例外" + e + "が送出されました。");
        }

        for (int i = 0; i < 10; i++) {
            try {
                // Threadクラスのクラスメソッド
                Thread.sleep(10);               // 10ミリ秒間、一時停止
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("mainメソッドの処理中です。");
        }
    }
}

< スレッドの同期 >

class SumClass {
	private int sumNum;

	public SumClass() {
		sumNum = 0;
	}

	// synchronized修飾子 : あるスレッドがメソッド呼び出し中は、別のスレッドからは呼び出せない。
	// synchronized修飾子を用いて、スレッドの同期をとることで、別スレッドの割り込みを防ぐ
	public synchronized void add(int addNum) {
		int x = sumNum;
		x += addNum;

		// 時間稼ぎ   ※他に、Thread.sleep(millis);を使う手もある
		for (int i = 0; i < 10000; i++) {
			;
		}

		sumNum = x;
		System.out.println("合計:" + sumNum);
	}
}

// Threadクラスを拡張したサブクラス
class Test extends Thread {
	private SumClass testSum; // SumClassクラス型の変数testSum

	public Test(SumClass sc) {
		testSum = sc;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			testSum.add(10);
		}
	}
}

public class Sample {

	public static void main(String[] args) {
		SumClass sumClass = new SumClass();

		Test test1 = new Test(sumClass);
		test1.start();

		Test test2 = new Test(sumClass);
		test2.start();
	}
}

アプレット

  • アプレット: 他のアプリケーション(多くの場合、Webブラウザ)の中に組み込まれて実行される小さなプログラムとのこと。
  • java.appletパッケージのAppletクラスを拡張したクラスを宣言する。
  • paintメソッド: アプレットを描画するとき、Webブラウザから呼び出される。
  • java.awtパッケージのGraphicsクラスのメソッドを利用するには、paintメソッドの引数でオブジェクトへの参照をする方法がある。
  • アプレットの基本的な流れ:
    init → (start → paint → run → stop) → destroy  ※()内はループ:stopから再開時: stop → start
    ※意図的な再描画時: repaint → update → paint
  • JavaのGUIツールキットには、Abstract Window Toolkit(AWT)と、それを拡張したSwingがある。
  • Javaプラットフォーム用ウィジェット・ツールキットの一種として、Standard Widget Toolkit(SWT)がある。
  • Javaアプレットは、アプレットビューアで実行する方法と、Webブラウザで実行する方法がある。

< アプレットビューアで実行する場合 >

  • (1) Eclipseからの実行
    ※サイズ指定(実行→実行構成→Javaアプレット→パラメーター)
  • (2) コマンドプロンプトからの実行 ※htmlファイルを用意しておく
    appletviewer ファイル名.html

< Webブラウザで実行する場合 >

  • Webブラウザを起動して、htmlファイルを開く。

< アプレット例 >

HTML5 ※後述のソースコード例全てに共通

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8" />
	<title>タイトル</title>
</head>
<body>
	<applet code="クラスファイル名.class" width="アプレット幅の数値" height="アプレット高さの数値"></applet>
</body>
</html>

ソースコード例(1)  ※文字,図形,画像の描画

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;

/**
 * 文字,図形,画像の描画処理を行う。
 * Appletクラスを拡張したクラス。
 *
 * @author 名前
 */
public class Sample extends Applet {
	Image img;

	/**
	 * ブラウザまたはアプレットビューアに呼び出され、このアプレットがシステムにロードされたことを通知する。
	 *
	 * @see java.applet.Applet#init()
	 */
	@Override
	public void init() {
		img = getImage(getDocumentBase(), "myImage.png");
	}

	/**
	 * このコンポーネントをペイントする。 コンポーネントが最初に表示される場合、または修復が必要な場合など、
	 * コンポーネントの内容をペイントする必要があるときにこのメソッドを呼び出す。
	 *
	 * @see java.awt.Container#paint(java.awt.Graphics)
	 */
	@Override
	public void paint(Graphics g) {
		Dimension d = getSize();
		g.setColor(Color.LIGHT_GRAY);
		g.fillRect(0, 0, d.width, d.height);  // 背景ではない

		g.drawImage(img, 0, 0, this);

		g.setColor(Color.BLUE);
		g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20));
		g.drawString("Hello,", 10, 30);

		g.setColor(Color.RED);
		g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 24));
		g.drawString("World!", 10, 60);

		g.setColor(Color.ORANGE);
		g.drawRect(10, 80, 150, 40);

		g.setColor(Color.GREEN);
		g.drawLine(10, 80, 160, 100);

		g.setColor(Color.GRAY);
		g.fillRect(10, 140, 150, 40);

		g.setColor(Color.YELLOW);
		g.clearRect(30, 150, 110, 20);
	}

}

ソースコード例(2)  ※マウスイベント

import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * マウスイベント処理をする。 Appletクラスを拡張し、MouseListenerインタフェースを実装している。
 *
 * @author 名前
 */
public class Sample extends Applet implements MouseListener {
	private int x = 20;
	private int y = 20;
	private String str = "マウスイベントの説明";
	private Color clr;

	public void changeString(String str) {
		this.str = str;
	}

	private void changeRectColor(Color clr) {
		this.clr = clr;
	}

	@Override
	public void init() {
		addMouseListener(this);
	}


	@Override
	public void paint(Graphics g) {
		g.setColor(Color.DARK_GRAY);
		g.setFont(new Font(Font.DIALOG, Font.BOLD, 10));
		g.drawString(str, 40, 30);

		g.setColor(clr);
		g.fillRect(x, y, 20, 20);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		x = e.getX();
		y = e.getY();

		changeString("マウスがクリックされました。");
		changeRectColor(Color.BLUE);
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		x = e.getX();
		y = e.getY();

		changeString("マウスがコンポーネントに入りました。");
		changeRectColor(Color.RED);
		repaint();

	}

	@Override
	public void mouseExited(MouseEvent e) {
		x = e.getX();
		y = e.getY();

		changeString("マウスがコンポーネントから出ました。");
		changeRectColor(Color.ORANGE);
		repaint();
	}

	@Override
	public void mousePressed(MouseEvent e) {
		x = e.getX();
		y = e.getY();

		changeString("マウスが押されました。※押された状態");
		changeRectColor(Color.CYAN);
		repaint();
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		x = e.getX();
		y = e.getY();

        // クリックとの違いをみるには、マウスを一度押した後、マウス位置をずらしてから離すと良く分かる。
		changeString("マウスがリリースされました。");
		changeRectColor(Color.MAGENTA);
		repaint();
	}
}

ソースコード例(3)  ※マウスイベント:特定の処理だけ記述する場合

import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * マウスイベント処理をする。 Appletクラスを拡張している。
 *
 * @author 名前
 */
public class Sample extends Applet {
	private int x = 20;
	private int y = 20;
	private String str = "マウスイベントの説明";
	private Color clr;

	/**
	 * 内部クラス(非staticな、ネストしたクラス)であり、必要なマウスイベント処理だけをオーバーライドしている。
	 * MouseAdapterクラスを拡張している。
	 * MouseAdapterクラスは、MouseListenerインタフェース等を実装しており、全てのメソッド内容が空。
	 */
	private class myMouseListener extends MouseAdapter {
		@Override
		public void mouseClicked(MouseEvent e) {
			// Sampleクラスのオブジェクト自身のフィールドxに代入 ※この例では内部クラスのフィールドやローカル変数にxは無いので、xだけでも可
			Sample.this.x = e.getX();
			y = e.getY();                             // Sample.this省略

			str = "マウスがクリックされました。";     // Sample.this省略
			clr = Color.BLUE;                         // Sample.this省略
			repaint();                                // Sample.this省略
		}
	}

	@Override
	public void init() {
		addMouseListener(new myMouseListener()); // 自作のマウスリスナーを指定
	}

	@Override
	public void paint(Graphics g) {
		g.setColor(Color.DARK_GRAY);
		g.setFont(new Font(Font.DIALOG, Font.BOLD, 10));
		g.drawString(str, 40, 30);

		g.setColor(clr);
		g.fillRect(x, y, 20, 20);
	}

}

ソースコード例(4)  ※ウィンドウツールのアクションイベント

import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * ボタンを押して画像の読込・消去をする。
 * Appletクラスを拡張し、ActionListenerインタフェースを実装している。
 *
 * @author 名前
 */
public class Sample extends Applet implements ActionListener {

	private Image img;
	private Button btn;
	private Boolean btnFlag = false;

	@Override
	public void init() {
		// setSize(300, 300); //このコンポーネントの大きさを指定する場合

		img = getImage(getDocumentBase(), "myImage.png");

		setLayout(null); //レイアウトを自分で指定するため、レイアウトマネージャーをnullにする。

		btn = new Button("イメージ読込");
		Dimension d = getSize();
		btn.setBounds(d.width / 2 - 100 / 2, 10, 100, 20);
		add(btn);
		btn.addActionListener(this);
	}

	@Override
	public void paint(Graphics g) {
		setBackground(Color.LIGHT_GRAY); // 背景色
		// setBackground(new Color(189, 189, 189)); //色の指定はこれでも可

		if (btnFlag) {
			g.drawImage(img, 0, 0, this);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (btnFlag) {
			btn.setLabel("イメージ読込");
			btnFlag = false;
			repaint();
		} else {
			btn.setLabel("イメージ消去");
			btnFlag = true;
			repaint();
		}
	}

}

ソースコード例(5)  ※アニメーション処理

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;

/**
 * 箱が動くアニメーション。 Appletクラスを拡張し、Runnableインタフェースを実装している。
 *
 * @author 名前
 */
public class Sample extends Applet implements Runnable {
	private int x = 20;
	private int y = 20;

	/**
	 * 一番最初に一度だけ実行される。
	 */
	@Override
	public void init() {
		Thread th = new Thread(this);
		th.start();
	}

	/**
	 * このメソッドの前に、一度 paintメソッドが実行される。
	 */
	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(100); // 0.1秒停止
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("例外" + e + "が発生しました。");
			}

			if (x != 200 && y == 20) {
				x += 5;
			} else if (x == 200 && y != 200) {
				y += 5;
			} else if (x != 20 && y == 200) {
				x -= 5;
			} else if (x == 20 && y != 20) {
				y -= 5;
			}

			repaint(); // 再描画
		}
	}

	/**
	 * runメソッドの前、及びrepaintメソッドが呼び出された時に、実行される。
	 */
	@Override
	public void paint(Graphics g) {
		g.setColor(Color.BLUE);
		g.fillRect(x, y, 30, 30);
	}

}

Swing

  • Swingクラス: javax.swingパッケージ
  • コンポーネント:何らかの機能を持った、プログラムの部品。
  • コンテナ:単一または複数のコンポーネントを含むことができる、コンポーネント。
    ※アプレット, コンテントペイン, JPanel などもコンテナ。
  • AWTでは、アプレットやフレーム等のトップレベルコンテナの上に直接コンポーネントを配置する。
  • Swingでは、アプレットやフレーム等のトップレベルコンテナの上にコンテントペイン(中間コンテナ)があり、その上にコンポーネントを配置する(メニューは別)。※JApplet, JFrame, JDialog, JWindow
  • Java 5の前までは、Swingでは、コンテントペインを自分で取得し、その上にコンポーネントを配置する必要があったが、Java SE 5 からは、自分で取得しなくても、直接コンポーネントを配置できる。※コンテントペインが無くなったわけではなく、デフォルトでコンテントペインに配置される。
  • イベントの種類には、MouseEvent, KeyEvent, ActionEvent, ItemEvent, ListSelectionEvent, WindowEvent などがある。

ソースコード例(1)  ※コンポーネントの追加

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;


/**
 * JAppletクラスのサブクラス。
 */
public class Sample extends JApplet {
	private JLabel lbl;
	private JTextField tfd;
	private JButton btn;

	@Override
	public void init() {
		// コンポーネントのオブジェクト作成
		lbl = new JLabel("ラベル");
		lbl.setForeground(Color.BLUE);
		lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		tfd = new JTextField("テキストフィールド");
		tfd.setForeground(Color.LIGHT_GRAY);
		tfd.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		btn = new JButton("ボタン");
		btn.setForeground(Color.DARK_GRAY);
		btn.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		// コンテントペインに、コンポーネント追加
		add(lbl, BorderLayout.NORTH);
		add(tfd, BorderLayout.CENTER);
		add(btn, BorderLayout.SOUTH);

		// -------------------------------------------------------------

		/*
		 * Java 5より前の書き方
		 *
		 * // コンテントペインを取得
		 * Container cnt = getContentPane();
		 *
		 * // コンポーネントのオブジェクト作成
		 * lbl= new JLabel("ラベル");
		 * lbl.setForeground(Color.BLUE);
		 * lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		 *
		 * tfd = new JTextField("テキストフィールド");
		 * tfd.setForeground(Color.LIGHT_GRAY);
		 * tfd.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		 *
		 * btn = new JButton("ボタン");
		 * btn.setForeground(Color.DARK_GRAY);
		 * btn.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
		 *
		 * // コンテントペインに、コンポーネント追加
		 * cnt.add(lbl, BorderLayout.NORTH);
		 * cnt.add(tfd, BorderLayout.CENTER);
		 * cnt.add(btn, BorderLayout.SOUTH);
		 */
	}
}

ソースコード例(2)  ※マウスイベント

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JApplet;
import javax.swing.JLabel;

public class Sample extends JApplet implements MouseListener {
    private JLabel lbl;

    @Override
    public void init() {
        // 全体の背景色
        getContentPane().setBackground(Color.LIGHT_GRAY);

        // コンポーネント作成
        lbl = new JLabel("ラベル");
        lbl.setForeground(Color.WHITE);
        lbl.setBackground(Color.DARK_GRAY);
        lbl.setOpaque(true);                  // ラベルの背景を表示するのに必要(不透明にする) ※opaque:不透明な
        lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));

        // コンポーネント追加
        add(lbl, BorderLayout.NORTH);

        // マウスリスナー追加
        addMouseListener(this);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        lbl.setForeground(Color.BLUE);
        lbl.setBackground(Color.YELLOW);  // 文字が見づらいので、ラベルの背景色を変える
        lbl.setText("マウスがクリックされました。");
    }

    @Override
    public void mousePressed(MouseEvent e) {
        lbl.setForeground(Color.CYAN);
        lbl.setBackground(Color.DARK_GRAY);
        lbl.setText("マウスが押されました。※押された状態");
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        lbl.setForeground(Color.MAGENTA);
        lbl.setBackground(Color.DARK_GRAY);
        lbl.setText("マウスがリリースされました。");
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        lbl.setForeground(Color.RED);
        lbl.setBackground(Color.DARK_GRAY);
        lbl.setText("マウスがコンポーネントに入りました。");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        lbl.setForeground(Color.ORANGE);
        lbl.setBackground(Color.DARK_GRAY);
        lbl.setText("マウスがコンポーネントから出ました。");
    }
}

ソースコード例(3)  ※マウスイベント:特定の処理だけ記述する場合

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JApplet;
import javax.swing.JLabel;

public class Sample extends JApplet {
	private JLabel lbl;

	@Override
	public void init() {
		// 全体の背景色
		getContentPane().setBackground(Color.LIGHT_GRAY);

		// コンポーネント作成
		lbl = new JLabel("ラベル");
		lbl.setForeground(Color.WHITE);
		lbl.setBackground(Color.DARK_GRAY);
		lbl.setOpaque(true); // ラベルの背景を表示するのに必要(不透明にする) ※opaque:不透明な
		lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));

		// コンポーネント追加
		add(lbl, BorderLayout.NORTH);

		// マウスリスナー追加
		addMouseListener(new MyMouseListener());  // イベント処理を、MyMouseListenerクラスのオブジェクトに委譲
	}

	// 内部クラス(非staticな、ネストされたクラス)
	// MouseAdapterクラスは、MouseListenerインタフェース等を実装しており、全てのメソッド内容が空。
	private class MyMouseListener extends MouseAdapter {
		@Override
		public void mouseClicked(MouseEvent e) {
			Sample.this.lbl.setForeground(Color.BLUE);    // Sample.this : Sampleクラスのオブジェクト自身
			lbl.setBackground(Color.YELLOW);              // Sample.this省略
			lbl.setText("マウスがクリックされました。");  // Sample.this省略
		}
	}
}

ソースコード例(4)  ※アクションイベント

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Sample extends JApplet implements ActionListener {
	private JLabel lbl;
	private JTextField tfd;
	private JButton btn1;
	private JButton btn2;
	private JPanel pnl;

	@Override
	public void init() {
		// コンポーネントのオブジェクト作成
		lbl = new JLabel("ラベル");
		lbl.setForeground(Color.BLUE);
		lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		tfd = new JTextField("テキストフィールド");
		tfd.setForeground(Color.LIGHT_GRAY);
		tfd.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		btn1 = new JButton("ラベル変更");
		btn1.setForeground(Color.DARK_GRAY);
		btn1.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		btn2 = new JButton("ラベル復元");
		btn2.setForeground(Color.DARK_GRAY);
		btn2.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

		pnl = new JPanel();

		// ボタンに、アクションリスナーを追加
		btn1.addActionListener(this);
		btn2.addActionListener(this);

		// パネルにボタンを追加
		pnl.add(btn1);
		pnl.add(btn2);

		// コンポーネント追加
		add(lbl, BorderLayout.NORTH);
		add(tfd, BorderLayout.CENTER);
		add(pnl, BorderLayout.SOUTH);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == btn1) {
			lbl.setText("ボタンが押されました。");
		}
		if (e.getSource() == btn2) {
			lbl.setText("ラベル");
		}
	}
}

ソースコード例(5)  ※キーイベント

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JApplet;
import javax.swing.JLabel;

public class Sample extends JApplet implements KeyListener {
	private JLabel lbl;

	@Override
	public void init() {
		// 全体の背景色
		getContentPane().setBackground(Color.LIGHT_GRAY);

		// コンポーネント作成
		lbl = new JLabel("ラベル");
		lbl.setForeground(Color.WHITE);
		lbl.setBackground(Color.DARK_GRAY);
		lbl.setOpaque(true);                // ラベルの背景を表示するのに必要(不透明にする) ※opaque:不透明な
		lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));

		// コンポーネント追加
		add(lbl, BorderLayout.NORTH);

		// マウスリスナー追加
		addKeyListener(this);
	}

	@Override
	public void keyPressed(KeyEvent e) {
		int keyCode = e.getKeyCode();
		switch (keyCode) {
		case KeyEvent.VK_A:
			lbl.setText("Aキーが押されました。");
			break;
		case KeyEvent.VK_B:
			lbl.setText("Bキーが押されました。");
			break;
		case KeyEvent.VK_C:
			lbl.setText("Cキーが押されました。");
			break;
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}
}

ソースコード例(6)  ※キーイベント:特定の処理だけ記述する場合

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JApplet;
import javax.swing.JLabel;

public class Sample extends JApplet {
	private JLabel lbl;

	@Override
	public void init() {
		// 全体の背景色
		getContentPane().setBackground(Color.LIGHT_GRAY);

		// コンポーネント作成
		lbl = new JLabel("ラベル");
		lbl.setForeground(Color.WHITE);
		lbl.setBackground(Color.DARK_GRAY);
		lbl.setOpaque(true);                  // ラベルの背景を表示するのに必要(不透明にする) ※opaque:不透明な
		lbl.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));

		// コンポーネント追加
		add(lbl, BorderLayout.NORTH);

		// マウスリスナー追加
		addKeyListener(new MyKeyListener());  // イベント処理を、MyKeyListenerクラスのオブジェクトに委譲
	}

	private class MyKeyListener extends KeyAdapter {
		@Override
		public void keyPressed(KeyEvent e) {
			int keyCode = e.getKeyCode();
			switch (keyCode) {
			case KeyEvent.VK_A:
				Sample.this.lbl.setText("Aキーが押されました。"); // Sample.this : Sampleクラスのオブジェクト自身
				break;
			case KeyEvent.VK_B:
				lbl.setText("Bキーが押されました。");             // Sample.this省略
				break;
			case KeyEvent.VK_C:
				lbl.setText("Cキーが押されました。");             // Sample.this省略
				break;
			}
		}
	}
}

レイアウトマネージャー

  • レイアウトマネージャー: コンポーネントの配置位置やサイズを管理する。
  • コンテナであるコンテントペインのレイアウトマネージャーを設定しなかった場合、自動的にボーダーレイアウトが設定される。この時、コンポーネントの配置位置を指定しなかった場合、自動的に中央に配置される。
    ※ボーダーレイアウト: コンポーネントを東西南北と中央の5箇所に配置できる。

ボーダーレイアウト

  • コンポーネントを東西南北・中央の5箇所に配置できる
import java.awt.BorderLayout;
 
import javax.swing.JApplet;
import javax.swing.JButton;
 
public class Sample extends JApplet {
    private JButton[] btn = new JButton[5];
 
    @Override
    public void init() {
        // コンポーネント作成
        btn[0] = new JButton("EAST");
        btn[1] = new JButton("WEST");
        btn[2] = new JButton("CENTER");
        btn[3] = new JButton("SOUTH");
        btn[4] = new JButton("NORTH");
 
        // コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
        setLayout(new BorderLayout());      // デフォルトがボーダーレイアウトなので、省略しても同じ
 
        // コンテントペインに配置
        add(btn[0], BorderLayout.EAST);     // 位置を指定しない場合は BorderLayout.CENTER
        add(btn[1], BorderLayout.WEST);
        add(btn[2], BorderLayout.CENTER);   // デフォルトの位置が BorderLayout.CENTER なので、位置は省略しても同じ
        add(btn[3], BorderLayout.SOUTH);
        add(btn[4], BorderLayout.NORTH);
    }
}

フローレイアウト

  • コンポーネントを横に並べて配置できる。※コンテナに入りきらない場合、折り返す。
import java.awt.FlowLayout;

import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton[] btn = new JButton[5];

	@Override
	public void init() {
		// コンポーネント作成
		for (int i = 0; i < btn.length; i++) {
			btn[i] = new JButton(Integer.toString(i));
		}

		// コンテントペインに、レイアウトマネージャーを設定 ※フローレイアウト
		setLayout(new FlowLayout());

		// コンテントペインに配置
		for (int i = 0; i < btn.length; i++) {
			add(btn[i]);
		}
	}
}

グリッドレイアウト

  • コンポーネントを、行・列の数を指定して格子状に配置できる。
  • 大きさはグリッド全体に広がる。複数のグリッドにわたる配置はできない。
import java.awt.GridLayout;

import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton[] btn = new JButton[5];

	@Override
	public void init() {
		// コンポーネント作成
		for (int i = 0; i < btn.length; i++) {
			btn[i] = new JButton(Integer.toString(i));
		}

		// コンテントペインに、レイアウトマネージャーを設定 ※グリッドレイアウト
		setLayout(new GridLayout(2, 3));      // 行・列の順

		// コンテントペインに配置
		for (int i = 0; i < btn.length; i++) {
			add(btn[i]);
		}
	}
}

カードレイアウト

  • コンポーネントを、カードを重ねたように配置できる。
import java.awt.CardLayout;

import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton[] btn = new JButton[5];

	@Override
	public void init() {
		// コンポーネント作成
		for (int i = 0; i < btn.length; i++) {
			btn[i] = new JButton(Integer.toString(i));
		}

		// コンテントペインに、レイアウトマネージャーを設定 ※カードレイアウト
		CardLayout cl = new CardLayout();
		setLayout(cl);

		// コンテントペインに配置
		for (int i = 0; i < btn.length; i++) {
			// カードに名前を付けて、コンポーネントを配置する。※一番最初に追加したものが表示されることになる。
			add("Card" + i, btn[i]);
		}

		// 表示するカードの切り替え  -------------------------------------------------------------------------

		// 指定されたコンテナにおける、指定された名前のカードに切り替える。
		cl.show(getContentPane(), "Card2");   // 結果: Card2 が表示される ※btn[2]

		// 指定されたコンテナにおける、最初のカードに切り替える。
		cl.first(getContentPane());           // 結果: Card0 が表示される ※btn[0]

		// 指定されたコンテナにおける、最後のカードに切り替える。
		cl.last(getContentPane());            // 結果: Card4 が表示される ※btn[4]

		// 指定されたコンテナにおける、前のカードに切り替える。最初の場合、最後になる。
		cl.previous(getContentPane());        // 結果: Card3 が表示される ※btn[3]

		// 指定されたコンテナにおける、次のカードに切り替える。最後の場合、最初になる。
		cl.next(getContentPane());            // 結果: Card4 が表示される ※btn[4]
	}
}

ボックスレイアウト

  • コンポーネントを横や縦に並べて配置できる。
  • 横に並べてコンテナに入りきらない場合、折り返しをしないのが、フローレイアウトと異なる。
import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton btn1, btn2, btn3;

	public void init() {
		// コンポーネント作成
		btn1 = new JButton("First");
		btn2 = new JButton("Second");
		btn3 = new JButton("Third");

		// コンテントペインに、レイアウトマネージャーを設定 ※ボックスレイアウト
		setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));   // この例では、Y軸方向に並べる

		// 整列の設定をする場合
		btn1.setAlignmentX(CENTER_ALIGNMENT);    // この例では、垂直の配置方法を設定
		btn2.setAlignmentX(CENTER_ALIGNMENT);
		btn3.setAlignmentX(CENTER_ALIGNMENT);

		// コンテントペインに、コンポーネントを設定
		add(btn1);
		add(btn2);
		add(btn3);
	}
}

グリッドバッグレイアウト

  • 同じ大きさや、異なる大きさのコンポーネントを、格子状に配置できる。
  • 複数のグリッドにわたる配置ができる事や、大きさや位置を自由に設定できる事が、グリッドレイアウトと異なる。
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton btn1, btn2, btn3, btn4;

	public void init() {
		// コンポーネント作成
		btn1 = new JButton("First");
		btn2 = new JButton("Second");
		btn3 = new JButton("Third");
		btn4 = new JButton("Fourth");

		// コンテントペインに、レイアウトマネージャーを設定 ※グリッドバッグレイアウト
		GridBagLayout gbl = new GridBagLayout();
		setLayout(gbl);

		// コンテントペインに、コンポーネントを設定
		// 引数: ボタン, グリッドバッグレイアウト, グリッド横位置, グリッド縦位置, グリッド幅, グリッド高さ
		addJButton(btn1, gbl, 0, 0, 1, 3);
		addJButton(btn2, gbl, 1, 0, 1, 1);
		addJButton(btn3, gbl, 1, 1, 1, 1);
		addJButton(btn4, gbl, 1, 2, 1, 1);
	}

	/**
	 * JButtonをコンテントペインに設定する自作メソッド。
	 * 引数: ボタン, グリッドバッグレイアウト, グリッド横位置, グリッド縦位置, グリッド幅, グリッド高さ
	 */
	private void addJButton(JButton btn, GridBagLayout gbl, int x, int y, int w, int h) {

		// グリッドバッグコンストレインツのオブジェクト作成
		// (GridBagLayoutクラスを使用してレイアウトされるコンポーネントの制約を指定するクラス)
		GridBagConstraints gbc = new GridBagConstraints();

		// コンポーネントが表示領域よりも小さい場合に、縦・横の領域いっぱいに拡大するかどうかを指定
		gbc.fill = GridBagConstraints.NONE;           // この例ではNONE(大きさ変更なし)を設定

		// コンポーネントが表示領域よりも小さい場合に、領域内での配置位置を指定
		gbc.anchor = GridBagConstraints.SOUTHEAST;    // この例ではSOUTHEAST(右下隅)を設定 ※デフォルトはCENTER

		// コンポーネントを配置するセルの、グリッドの位置 ※0から数える
		gbc.gridx = x;                                // グリッドの横位置
		gbc.gridy = y;                                // グリッドの縦位置

		// コンポーネントを配置するセルの、グリッド幅・高さを指定 ※デフォルトは1
		gbc.gridwidth = w;                            // グリッド幅
		gbc.gridheight = h;                           // グリッド高さ

		// グリッドバッグレイアウトにおける、ボタンに対して、
		// 制約(ここまで設定してきたグリッドバッグコンストレインツ)を設定
		gbl.setConstraints(btn, gbc);

		// コンテントペインに、ボタンを設定する
		add(btn);
	}
}

パネルによるレイアウト

  • コンテナの一種であるパネルに、コンポーネントを配置できる。
import java.awt.GridLayout;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Sample extends JApplet {
	private JPanel[] pnl = new JPanel[2]; // パネル(コンテナのひとつ)
	private JButton[] btn = new JButton[10];

	@Override
	public void init() {
		// コンポーネント作成
		for (int i = 0; i < pnl.length; i++) {
			pnl[i] = new JPanel();
		}
		for (int i = 0; i < btn.length; i++) {
			btn[i] = new JButton(Integer.toString(i));
		}

		// ------------------------------------------------------------------------
		// コンテントペインに、レイアウトマネージャーを設定 ※グリッドレイアウト
		setLayout(new GridLayout(2, 1)); // 行・列の順

		// コンテントペインに、パネルを配置
		for (int i = 0; i < pnl.length; i++) {
			add(pnl[i]);
		}

		// ------------------------------------------------------------------------
		// パネルに、レイアウトマネージャーを設定 ※グリッドレイアウト
		pnl[0].setLayout(new GridLayout(2, 2)); // 行・列の順
		pnl[1].setLayout(new GridLayout(2, 3));

		// パネルに、コンポーネントを配置
		for (int i = 0; i < btn.length; i++) {
			if (i < 4) {
				pnl[0].add(btn[i]);
			} else {
				pnl[1].add(btn[i]);
			}
		}
	}
}

絶対位置を指定したレイアウト

  • レイアウトマネージャーをnullにして、絶対位置指定でコンポーネントを配置できる。
import javax.swing.JApplet;
import javax.swing.JButton;

public class Sample extends JApplet {
	private JButton[] btn = new JButton[5];

	public void init() {
		// コンポーネント作成
		btn[0] = new JButton("First");
		btn[1] = new JButton("Second");
		btn[2] = new JButton("Third");
		btn[3] = new JButton("Fourth");
		btn[4] = new JButton("Fifth");

		// コンポーネントを、絶対位置指定で配置する場合、
		// コンテナ(この例ではコンテントペイン)の、レイアウトマネージャーを "無し(null)" に設定
		setLayout(null);

		// --------------------------------------------------------------------------------------------
		// コンポーネントの位置と大きさを設定 ※別々に設定する場合
		btn[0].setLocation(10, 10);    // 位置
		btn[0].setSize(100, 50);       // 大きさ

		// コンポーネントの位置と大きさを設定 ※一度に両方設定する場合
		btn[1].setBounds(10, 70, 200, 50);

		// --------------------------------------------------------------------------------------------
		// コンポーネントを重ねる
		for (int i = 2; i < btn.length; i++) {
			// コンポーネントの重なる順序(Zオーダー)は、後に追加したものが、後ろに表示される
			btn[i].setBounds(i * 10 - 10, i * 10 + 110, 100, 50);       // この例ではbtn[2]が一番手前
		}

		// コンテントペインに、コンポーネントを設定
		for (int i = 0; i < btn.length; i++) {
			add(btn[i]);
		}
	}
}

ラベル

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import javax.swing.border.TitledBorder;

public class Sample extends JApplet {
	private JLabel[] lbl = new JLabel[5]; // ラベル
	private ImageIcon myLabelIcon;        // ラベル用アイコン
	private ImageIcon myBorderIcon;       // ボーダー用アイコン

	@Override
	public void init() {
		// コンポーネント作成
		for (int i = 0; i < lbl.length; i++) {
			lbl[i] = new JLabel("ラベル" + i);
		}
		myLabelIcon = new ImageIcon(getImage(getDocumentBase(), "myLabelIcon.png"));
		myBorderIcon = new ImageIcon(getImage(getDocumentBase(), "myBorderIcon.png"));

		// ラベルのボーダーを設定
		lbl[0].setBorder(new BevelBorder(BevelBorder.RAISED, Color.WHITE, Color.DARK_GRAY));
		lbl[1].setBorder(new LineBorder(Color.ORANGE, 5));
		lbl[2].setBorder(new TitledBorder("ボーダー"));
		lbl[3].setBorder(new EtchedBorder());
		lbl[4].setBorder(new MatteBorder(10, 10, 10, 10, myBorderIcon)); // ボーダー用アイコン

		// -----------------------------------------------------------------------------------------
		// ラベルにアイコンを設定
		lbl[0].setIcon(myLabelIcon);
		lbl[1].setIcon(myLabelIcon);
		lbl[2].setIcon(myLabelIcon);
		lbl[3].setIcon(myLabelIcon);
		lbl[4].setIcon(myLabelIcon);

		// ラベルとアイコンの水平位置を設定
		lbl[0].setHorizontalTextPosition(JLabel.LEFT);
		lbl[1].setHorizontalTextPosition(JLabel.LEFT);
		lbl[2].setHorizontalTextPosition(JLabel.CENTER);
		lbl[3].setHorizontalTextPosition(JLabel.RIGHT);
		lbl[4].setHorizontalTextPosition(JLabel.RIGHT);

		// ラベルとアイコンの垂直位置を設定
		lbl[0].setVerticalTextPosition(JLabel.TOP);
		lbl[1].setVerticalTextPosition(JLabel.TOP);
		lbl[2].setVerticalTextPosition(JLabel.CENTER);
		lbl[3].setVerticalTextPosition(JLabel.BOTTOM);
		lbl[4].setVerticalTextPosition(JLabel.BOTTOM);

		// -----------------------------------------------------------------------------------------
		// ラベルのフォントを設定
		lbl[0].setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
		lbl[1].setFont(new Font(Font.SERIF, Font.ITALIC, 18));
		lbl[2].setFont(new Font(Font.DIALOG, Font.BOLD, 20));
		lbl[3].setFont(new Font(Font.MONOSPACED, Font.PLAIN, 18));
		lbl[4].setFont(new Font(Font.DIALOG_INPUT, Font.PLAIN, 15));

		// ラベルの前景色を設定
		lbl[0].setForeground(Color.BLUE);
		lbl[1].setForeground(Color.YELLOW);
		lbl[2].setForeground(Color.CYAN);
		lbl[3].setForeground(Color.GREEN);
		lbl[4].setForeground(Color.MAGENTA);

		// ラベルの背景色を設定
		lbl[0].setBackground(Color.YELLOW);
		lbl[1].setBackground(Color.BLUE);
		lbl[2].setBackground(Color.MAGENTA);
		lbl[3].setBackground(Color.DARK_GRAY);
		lbl[4].setBackground(Color.BLACK);

		// ラベルの不透明の設定
		lbl[0].setOpaque(true);      // テキスト周りが、不透明になる
		lbl[1].setOpaque(true);
		lbl[2].setOpaque(true);
		lbl[3].setOpaque(true);
		lbl[4].setOpaque(false);     // テキスト周りが、透明になる ※デフォルトなので省略しても同じ

		// 水平方向の位置を設定
		lbl[0].setHorizontalAlignment(JLabel.LEFT);
		lbl[1].setHorizontalAlignment(JLabel.LEFT);
		lbl[2].setHorizontalAlignment(JLabel.CENTER);
		lbl[3].setHorizontalAlignment(JLabel.RIGHT);
		lbl[4].setHorizontalAlignment(JLabel.RIGHT);

		// 垂直方向の位置を設定
		lbl[0].setVerticalAlignment(JLabel.TOP);
		lbl[1].setVerticalAlignment(JLabel.TOP);
		lbl[2].setVerticalAlignment(JLabel.CENTER);
		lbl[3].setVerticalAlignment(JLabel.BOTTOM);
		lbl[4].setVerticalAlignment(JLabel.BOTTOM);

		// ------------------------------------------------------------------------
		// コンテントペインに、レイアウトマネージャーを設定 ※グリッドレイアウト
		setLayout(new GridLayout(5, 1, 0, 10));         // 行・列の順

		// コンテントペインに、コンポーネントを配置
		for (int i = 0; i < lbl.length; i++) {
			add(lbl[i]);
		}
	}
}

ボタン

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;

public class Sample extends JApplet {
	private JLabel lbl;                   // ラベル
	private JButton btn;                  // ボタン
	private ImageIcon myButtonIcon;       // ボタン用アイコン

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ボタンを押してください。");
		btn = new JButton("ボタン");

		// ボタンにアイコンを配置
		myButtonIcon = new ImageIcon(getImage(getDocumentBase(), "myButtonIcon.png"));
		btn.setIcon(myButtonIcon);
		btn.setHorizontalTextPosition(JButton.CENTER);
		btn.setVerticalTextPosition(JButton.CENTER);

		// コンポーネントに、アクションリスナーを設定
		btn.addActionListener(new MyActionListener());

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());     // 省略可

		// コンテントペインに、コンポーネントを配置
		add(lbl, BorderLayout.NORTH);
		add(btn, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			btn.setEnabled(false);
			lbl.setText("ボタンが無効になりました。");
		}
	}
}

ラジオボタン

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class Sample extends JApplet {
	private JLabel lbl;             // ラベル
	private JPanel pnl;             // パネル
	private JRadioButton rb1, rb2;  // ラジオボタン
	private ButtonGroup bg;         // ボタングループ

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ラジオボタンを選んでください。");
		pnl = new JPanel();
		rb1 = new JRadioButton("ラジオボタン1");
		// rb1 = new JRadioButton("ラジオボタン1", true);  // 最初から選択状態のラジオボタンを作成する場合
		rb2 = new JRadioButton("ラジオボタン2");

		// コンポーネントに、アクションリスナーを設定
		rb1.addActionListener(new MyActionListener());
		rb2.addActionListener(new MyActionListener());

		// ラジオボタンをボタングループに設定する
		bg = new ButtonGroup();
		bg.add(rb1);
		bg.add(rb2);

		// パネルに、コンポーネントを配置
		pnl.add(rb1);
		pnl.add(rb2);

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());               // 省略可

		// コンテントペインに、コンポーネント(ラベルとパネル)を配置
		add(lbl, BorderLayout.NORTH);
		add(pnl, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JRadioButton localRb = (JRadioButton) e.getSource();
			lbl.setText(localRb.getText() + "が選択されました。");
		}
	}
}

チェックボックス

import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JApplet;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Sample extends JApplet {
	private JLabel lbl; // ラベル
	private JPanel pnl; // パネル
	private JCheckBox cb1, cb2; // チェックボックス

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("チェックボックスを選んでください。");
		pnl = new JPanel();
		cb1 = new JCheckBox("チェックボックス1");
		cb2 = new JCheckBox("チェックボックス2");

		// コンポーネントに、アイテムリスナーを設定
		cb1.addItemListener(new MyItemListener());
		cb2.addItemListener(new MyItemListener());

		// パネルに、コンポーネントを配置
		pnl.add(cb1);
		pnl.add(cb2);

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());       // 省略可

		// コンテントペインに、コンポーネント(ラベルとパネル)を配置
		add(lbl, BorderLayout.NORTH);
		add(pnl, BorderLayout.SOUTH);
	}

	private class MyItemListener implements ItemListener {
		@Override
		public void itemStateChanged(ItemEvent e) {
			JCheckBox localCb = (JCheckBox) e.getSource();
			if (e.getStateChange() == ItemEvent.SELECTED) {
				lbl.setText(localCb.getText() + "が選択されました。");
			} else if (e.getStateChange() == ItemEvent.DESELECTED) {
				lbl.setText(localCb.getText() + "が非選択になりました。");
			}
		}
	}
}

テキストフィールド

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class Sample extends JApplet {
	private JLabel lbl;       // ラベル
	private JTextField tfd;   // テキストフィールド

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("テキストフィールドに文字を入力をしてください。");
		tfd = new JTextField("テキストフィールド");

		// コンポーネントに、アクションリスナーを設定
		tfd.addActionListener(new MyActionListener());

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());     // 省略可

		// コンテントペインに、コンポーネントを配置
		add(lbl, BorderLayout.NORTH);
		add(tfd, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JTextField localTfd = (JTextField) e.getSource();
			lbl.setText(localTfd.getText() + "が入力されました。");
		}
	}
}

テキストエリア

import java.awt.BorderLayout;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JTextArea;

public class Sample extends JApplet {
	private JLabel lbl;       // ラベル
	private JTextArea ta;     // テキストエリア

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ラベル");
		ta = new JTextArea("テキストエリア");

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());     // 省略可

		// コンテントペインに、コンポーネントを配置
		add(lbl, BorderLayout.NORTH);
		add(ta, BorderLayout.CENTER);
	}
}

リスト

import java.awt.BorderLayout;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Sample extends JApplet {
	private JLabel lbl; // ラベル
	private JList li; // リスト
	private JScrollPane sp; // スクロールペイン

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("リストを選んでください。");
		String[] str = { "戦艦", "空母", "潜水艦", "戦闘機", "戦車" };
		li = new JList(str);
		sp = new JScrollPane(li);

		// コンポーネントに、リストセレクションリスナーを設定
		li.addListSelectionListener(new MyListSelectionListener());

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout()); // 省略可

		// コンテントペインに、コンポーネント(ラベルとスクロールペイン)を配置
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
	}

	private class MyListSelectionListener implements ListSelectionListener {
		@Override
		public void valueChanged(ListSelectionEvent e) {
			JList localLi = (JList) e.getSource();
			String localStr = (String) localLi.getSelectedValue();
			lbl.setText(localStr + "が選択されました。");
		}
	}
}

コンボボックス

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JComboBox;
import javax.swing.JLabel;

public class Sample extends JApplet {
	private JLabel lbl; // ラベル
	private JComboBox cb; // コンボボックス

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("コンボボックスから項目を選んでください。");
		String[] str = { "戦艦", "空母", "潜水艦", "戦闘機", "戦車" };
		cb = new JComboBox(str);

		// コンポーネントに、アクションリスナーを設定
		cb.addActionListener(new MyActionListener());

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout()); // 省略可

		// コンテントペインに、コンポーネント(ラベルとコンボボックス)を配置
		add(lbl, BorderLayout.NORTH);
		add(cb, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JComboBox localCb = (JComboBox) e.getSource();
			String localStr = (String) localCb.getSelectedItem();
			lbl.setText(localStr + "が選択されました。");
		}
	}
}

テーブル

import java.awt.BorderLayout;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Sample extends JApplet {
	private JLabel lbl;        // ラベル
	private JScrollPane sp;    // スクロールペイン
	private JTable tb;         // テーブル

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("元素と元素記号");
		lbl.setHorizontalAlignment(JLabel.CENTER);
		String[] columnNames = { "原子番号", "元素名", "元素記号", };
		String[][] rowData = { { "1", "水素", "H" }, { "2", "ヘリウム", "He" },
				{ "3", "リチウム", "Li" }, { "4", "ベリリウム", "Be" }, { "5", "ホウ素", "B" } };
		tb = new JTable(rowData, columnNames);
		sp = new JScrollPane(tb);

		// コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
		setLayout(new BorderLayout());    // 省略可

		// コンテントペインに、コンポーネント(ラベルとパネル)を配置
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
	}
}

メニューバー

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class Sample extends JApplet {
    private JLabel lbl;                            // ラベル
    private JMenuBar mb;                           // メニューバー
    private JMenu[] menu = new JMenu[4];           // メニュー
    private JMenuItem[] mi = new JMenuItem[8];     // メニューアイテム

    @Override
    public void init() {
        // ラベル作成
        lbl = new JLabel("メニューを選んでください。");

        // メニュー
        menu[0] = new JMenu("メニュー 1");
        menu[1] = new JMenu("サブメニュー 1");
        menu[2] = new JMenu("メニュー 2");
        menu[3] = new JMenu("サブメニュー 2");

        // メニューアイテム
        mi[0] = new JMenuItem("メニューアイテム 1");
        mi[1] = new JMenuItem("メニューアイテム 2");
        mi[2] = new JMenuItem("メニューアイテム 3");
        mi[3] = new JMenuItem("メニューアイテム 4");
        mi[4] = new JMenuItem("メニューアイテム 5");
        mi[5] = new JMenuItem("メニューアイテム 6");
        mi[6] = new JMenuItem("メニューアイテム 7");
        mi[7] = new JMenuItem("メニューアイテム 8");

        // メニュー 1 設定 ---------------------------------------
        menu[0].add(mi[0]);
        menu[0].add(mi[1]);
        menu[0].addSeparator();         // セパレータ追加
        menu[0].add(menu[1]);

        menu[1].add(mi[2]);
        menu[1].add(mi[3]);

        // メニュー 2 設定 ---------------------------------------
        menu[2].add(mi[4]);
        menu[2].add(menu[3]);
        menu[2].add(mi[7]);

        menu[3].add(mi[5]);
        menu[3].add(mi[6]);

        // メニューバーに、メニューを設定
        mb = new JMenuBar();
        mb.add(menu[0]);
        mb.add(menu[2]);

        // メニューアイテムに、アクションリスナーを設定
        for (int i = 0; i < mi.length; i++) {
            mi[i].addActionListener(new MyActionListener());
        }

        // コンテントペインに、レイアウトマネージャーを設定 ※ボーダーレイアウト
        setLayout(new BorderLayout());        // 省略可

        // コンテントペインに、コンポーネント(ラベルとパネル)を配置
        add(mb, BorderLayout.NORTH);
        add(lbl, BorderLayout.CENTER);
    }

    private class MyActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JMenuItem localMi = (JMenuItem) e.getSource();
            lbl.setText(localMi.getText() + "が選択されました。");
        }
    }
}

ツールバー

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JToolBar;

public class Sample extends JApplet {
	private JLabel lbl;                            // ラベル
	private JToolBar tb;                           // ツールバー
	private ImageIcon[] icon = new ImageIcon[5];   // イメージアイコン
	private JButton[] btn = new JButton[5];        // ボタン

	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ツールを選択してください。");
		tb = new JToolBar("ツールバー");

		// ボタン用のアイコンを用意
		for (int i = 0; i < icon.length; i++) {
			icon[i] = new ImageIcon(getImage(getDocumentBase(), "myButtonIcon" + i + ".png"));
		}

		// ボタンに、アイコンを設定
		for (int i = 0; i < btn.length; i++) {
			btn[i] = new JButton(icon[i]);
		}

		// ボタンに、ツールヒントを設定
		for (int i = 0; i < btn.length; i++) {
			btn[i].setToolTipText((i + 1) + "番目のツール");
		}

		// ボタンに、アクションリスナーを設定
		for (int i = 0; i < btn.length; i++) {
			btn[i].addActionListener(new MyActionListener());
		}

		// ツールバーに、ボタンを設定
		for (int i = 0; i < btn.length; i++) {
			if (i != 3) {
				tb.add(btn[i]);
			} else {
				tb.addSeparator(); // 4番目のツールの前にセパレータを追加
				tb.add(btn[i]);    // 4番目のツール
			}
		}

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(tb, BorderLayout.NORTH);
		add(lbl, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JButton localBtn = (JButton) e.getSource();

			int buttonNum = -1;
			for (int i = 0; i < btn.length; i++) {
				if (localBtn == btn[i]) {
					buttonNum = i + 1;
					break;
				}
			}

			lbl.setText(buttonNum +"番目のツールが選択されました。");
		}
	}
}

ダイアログ

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class Sample extends JApplet {
	private JLabel lbl;     // ラベル
	private JButton btn;    // ボタン

	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ボタンを押すと、ダイアログを表示します。");
		btn = new JButton("ダイアログを表示");

		// コンポーネントに、アクションリスナーを設定
		btn.addActionListener(new MyActionListener());

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(btn, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			Container parentComponent = getContentPane();
			String message = "メッセージ内容";
			String title = "メッセージダイアログ";
			int messageType = JOptionPane.INFORMATION_MESSAGE;
			JOptionPane.showMessageDialog(parentComponent, message, title,
					messageType);
		}
	}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class Sample extends JApplet {
	private JLabel lbl;     // ラベル
	private JButton btn;    // ボタン

	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ボタンを押すと、ダイアログを表示します。");
		btn = new JButton("ダイアログを表示");

		// コンポーネントに、アクションリスナーを設定
		btn.addActionListener(new MyActionListener());

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(btn, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			Container parentComponent = getContentPane();
			String message = "メッセージ内容";
			String title = "確認ダイアログ";
			int optionType = JOptionPane.YES_NO_OPTION;
			int res = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType);

			if(res == JOptionPane.YES_OPTION){
				String messageYes = "はい(Y) が選択されました。";
				String titleYes = "Yesメッセージダイアログ";
				int messageTypeYes = JOptionPane.INFORMATION_MESSAGE;
				JOptionPane.showMessageDialog(parentComponent, messageYes, titleYes, messageTypeYes);
			}

			if(res == JOptionPane.NO_OPTION){
				String messageNo = "いいえ(N) が選択されました。";
				String titleNo = "Noメッセージダイアログ";
				int messageTypeNo = JOptionPane.INFORMATION_MESSAGE;
				JOptionPane.showMessageDialog(parentComponent, messageNo, titleNo, messageTypeNo);
			}
		}
	}
}

MVC (Model View Controller)

  • MVC :  ユーザーインタフェースを持つアプリケーションソフトウェアを実装するためのデザインパターン。
  • model : アプリケーションデータ、ビジネスルール、ロジック、関数。
  • view: グラフや図などの任意の情報表現。
  • controller: 入力を受け取り model と view への命令に変換する。
  • Swingでは、view と controller を纏めて、一つの UI (user-interface) オブジェクト としている。
    ※ "modified MVC" や "Separable model architecture"  と呼ばれることがある。
import java.awt.BorderLayout;
import java.text.DateFormat;
import java.util.Calendar;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Sample extends JApplet {
	private JLabel lbl;
	private JTable tb;
	private JScrollPane sp;

	public void init() {
		// コンポーネント作成
		lbl = new JLabel("カレンダー");
		tb = new JTable(new MyTableModel());
		sp = new JScrollPane(tb);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
	}

	private class MyTableModel extends AbstractTableModel {
		private DateFormat df;

		public MyTableModel() {
			df = DateFormat.getDateInstance();  // デフォルトのフォーマットスタイルを持つ日付フォーマッタを取得
		}

		@Override
		public int getRowCount() {
			return 7;                   // 行数: 7
		}

		@Override
		public int getColumnCount() {
			return 2;                   // 列数: 2
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			Calendar ca = Calendar.getInstance();      // カレンダー取得
			ca.add(Calendar.DAY_OF_WEEK, rowIndex);    // カレンダーの現在時刻から、rowIndexの数値分だけ日数を加算する

			switch (columnIndex) {
			case 0:
				return df.format(ca.getTime());
			case 1:
				switch (ca.get(Calendar.DAY_OF_WEEK)) {
				case Calendar.SUNDAY:
					return "日";
				case Calendar.MONDAY:
					return "月";
				case Calendar.TUESDAY:
					return "火";
				case Calendar.WEDNESDAY:
					return "水";
				case Calendar.THURSDAY:
					return "木";
				case Calendar.FRIDAY:
					return "金";
				case Calendar.SATURDAY:
					return "土";
				}
			default:
				return "";
			}
		}

		@Override
		public String getColumnName(int column) {
			switch (column) {
			case 0:
				return "日付";
			case 1:
				return "曜日";
			default:
				return "";
			}
		}
	}
}
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class Sample {
	public static void main(String[] args) {

		// 使用可能なLookAndFeelを調べる
		// 使用可能なLookAndFeel実装を表す、LookAndFeelInfoの配列を返す
		LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();

		for (int i = 0; i < laf.length; i++) {
			System.out.println(laf[i].getClassName());  // ClassName
			System.out.println(laf[i].getName());       // Name
		}
	}
}
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class Sample extends JApplet {
	private JLabel lbl;                                // ラベル
	private JList li;                                  // リスト
	private JScrollPane sp;                            // スクロールペイン
	private ButtonGroup bg;                            // ボタングループ
	private JPanel pnl;                                // パネル
	private JRadioButton[] rb = new JRadioButton[5];   // ラジオボタン

	public void init() {
		// コンポーネント作成
		lbl = new JLabel("ラジオボタンを選択してください。");

		String[] listData = { "リスト1", "リスト2", "リスト3", "リスト4", "リスト5" };
		li = new JList(listData);
		sp = new JScrollPane(li);

		rb[0] = new JRadioButton("Metal");
		rb[1] = new JRadioButton("Nimbus");
		rb[2] = new JRadioButton("CDE/Motif");
		rb[3] = new JRadioButton("Windows");
		rb[4] = new JRadioButton("Windows Classic");

		// ラジオボタンに、アクションリスナーを設定
		for (int i = 0; i < rb.length; i++) {
			rb[i].addActionListener(new MyActionListener());
		}

		// ラジオボタンを、ボタングループに設定
		bg = new ButtonGroup();
		for (int i = 0; i < rb.length; i++) {
			bg.add(rb[i]);
		}

		// パネルに、ラジオボタンを設定
		pnl = new JPanel();
		for (int i = 0; i < rb.length; i++) {
			pnl.add(rb[i]);
		}

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
		add(pnl, BorderLayout.SOUTH);
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JRadioButton localRb = (JRadioButton) e.getSource();

			// LookAndFeelを設定
			// 引数には、LookAndFeelのクラスか、クラス名の文字列(String)を指定する
			try {
				if (localRb == rb[0]) {
					// Metal
					UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
				} else if (localRb == rb[1]) {
					// Nimbus
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
				} else if (localRb == rb[2]) {
					// CDE/Motif
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
				} else if (localRb == rb[3]) {
					// Windows
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
				} else if (localRb == rb[4]) {
					// Windows Classic
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				System.out.println("例外" + ex + "が発生しました。");
			}

			// いづれのLookAndFeelが選択されても画面を更新して、LookAndFeelを反映させる
			SwingUtilities.updateComponentTreeUI(getContentPane());
		}
	}
}

レンダラー

  • コンポーネントの中には、表示を "レンダラー" のオブジェクトが管理し、データは "モデル" のオブジェクトが管理するものがある。
    ※JComboBox, JList, JTable, JTree 等。
  • レンダラー:  "セル" (各項目)の表示を行うクラス。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Sample extends JApplet {
	private JLabel lbl;        // ラベル
	private JList li;          // リスト
	private JScrollPane sp;    // スクロールペイン

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("リストを選択してください。");
		String[] listData = { "リスト1", "リスト2", "リスト3", "リスト4", "リスト5" };
		li = new JList(listData);
		sp = new JScrollPane(li);

		// リストに、レンダラーを設定
		li.setCellRenderer(new MyListCellRenderer());

		// リストに、リストセレクションリスナーを設定
		li.addListSelectionListener(new MyListSelectionListener());

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
	}

	/**
	 * JListに設定するレンダラー。JLabelのメソッドを利用している。
	 */
	private class MyListCellRenderer implements ListCellRenderer {
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			// JLabelのメソッドを利用するため、ラベルのオブジェクトを作成
			JLabel cellLabel = new JLabel();         // このクラス自体を、JLabelクラスから拡張する方法もある

			// テキストの設定
			cellLabel.setForeground(Color.BLUE);
			cellLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20));
			cellLabel.setText(value.toString());

			// アイコンを設定
			ImageIcon icon = new ImageIcon(getImage(getDocumentBase(), "MyListIcon.png"));
			cellLabel.setIcon(icon);

			// リストの選択によって、背景色を変更する
			if (isSelected) {
				cellLabel.setOpaque(true);                       // 背景色が見えるように、コンポーネントを不透明にする
				cellLabel.setBackground(Color.PINK);
			} else {
				cellLabel.setOpaque(false);
				cellLabel.setBackground(list.getBackground());   // この例では、省略しても同じ
			}

			return cellLabel;        // このクラス自体を、JLabelクラスから拡張した場合は、thisを返す
		}
	}

	private class MyListSelectionListener implements ListSelectionListener {
		@Override
		public void valueChanged(ListSelectionEvent e) {
			JList localLi = (JList) e.getSource();
			String localStr = (String) localLi.getSelectedValue();
			lbl.setText(localStr + "が選択されました。");
		}
	}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Sample extends JApplet {
	private JLabel lbl;         // ラベル
	private JList li;           // リスト
	private JScrollPane sp;     // スクロールペイン

	@Override
	public void init() {
		// コンポーネント作成
		lbl = new JLabel("リストを選択してください。");
		String[] listData = { "リスト1", "リスト2", "リスト3", "リスト4", "リスト5" };
		li = new JList(listData);
		sp = new JScrollPane(li);

		// リストに、レンダラーを設定
		li.setCellRenderer(new MyListCellRenderer());

		// リストに、リストセレクションリスナーを設定
		li.addListSelectionListener(new MyListSelectionListener());

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
	}

	/**
	 * JListに設定するレンダラーであり、JPanelのサブクラスとする。JPanelのメソッドを利用している。
	 */
	private class MyListCellRenderer extends JPanel implements ListCellRenderer {
		private String cellStr;
		private int cellIndex;
		private boolean cellIsSelected;

		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {

			// テキスト
			this.cellStr = value.toString();

			// セルのインデックス
			this.cellIndex = index;

			// セルの選択状況
			this.cellIsSelected = isSelected;

			// セルの大きさ
			this.setPreferredSize(new Dimension(200, 50));

			return this;         // thisを返す。省略不可
		}

		@Override
		public void paint(Graphics g) {

			// テキスト描画
			g.setColor(Color.BLUE);
			g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20));
			g.drawString(cellStr, 50 + this.cellIndex * 10, 32);   // インデックスの値を利用して文字の位置をずらしてみる

			// アイコン用イメージを設定
			Image img = getImage(getDocumentBase(), "MyListIcon.png");
			g.drawImage(img, 0, 0, this);

			// リストの選択によって、表示を変更する
			if (cellIsSelected) {
				g.setColor(Color.PINK);
				g.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1);
			}
		}
	}

	private class MyListSelectionListener implements ListSelectionListener {
		@Override
		public void valueChanged(ListSelectionEvent e) {
			JList localLi = (JList) e.getSource();
			String localStr = (String) localLi.getSelectedValue();
			lbl.setText(localStr + "が選択されました。");
		}
	}
}

ウィンドウアプリケーション

  • AWTでは、Frameクラスを使用して、ウィンドウアプリケーションを作成できる。
  • Swingでは、JFrameクラスを使用して、ウィンドウアプリケーションを作成できる。
import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;

public class Sample extends JFrame {
	private JLabel lbl;        // ラベル
	private JList li;          // リスト
	private JScrollPane sp;    // スクロールペイン

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	/**
	 * コンストラクタ
	 */
	public Sample() {
		// タイトル
		super("タイトル");

		// コンポーネント作成
		lbl = new JLabel("ラベルです。");
		String[] listData = { "リスト1", "リスト2", "リスト3", "リスト4", "リスト5" };
		li = new JList(listData);
		sp = new JScrollPane(li);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);

		// フレームの設定
		setSize(300, 300);                                // コンポーエントのサイズ
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   // クローズで、アプリケーションが終了するように設定
		setVisible(true);                                 // Window表示
	}
}
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;

public class Sample extends JFrame {
	private JLabel lbl;        // ラベル
	private JList li;          // リスト
	private JScrollPane sp;    // スクロールペイン

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	/**
	 * コンストラクタ
	 */
	public Sample() {
		// タイトル
		super("タイトル");

		// コンポーネント作成
		lbl = new JLabel("ラベルです。");
		String[] listData = { "リスト1", "リスト2", "リスト3", "リスト4", "リスト5" };
		li = new JList(listData);
		sp = new JScrollPane(li);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);

		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());

		// フレームの設定
		setSize(300, 300);                                // コンポーエントのサイズ
		setVisible(true);                                 // Window表示
	}

	private class MyWindowListener extends WindowAdapter{
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}
}

ファイル操作

  • ファイル選択のダイアログを扱うには、Swingのファイルチューザー(javax.swing.JFileChooserクラス)が利用できる。
// コマンドラインから実行する
// java Sample beforeFile.txt afterFile.txt

import java.io.File;

public class Sample {
	public static void main(String[] args) {
		if (args.length != 2) {
			System.out.println("コマンドライン引数は、ファイル名と、変更したいファイル名の2つを指定してください。");
			System.exit(1);
		}

		// ファイルパスを元に、ファイルオブジェクト作成
		File file1 = new File(args[0]);

		// ファイル情報の表示 -----------------------------------------------------------------------------------------
		System.out.println("ファイル名:" + file1.getName());                // ファイル名
		System.out.println("絶対パスは:" + file1.getAbsolutePath());        // 絶対パス
		System.out.println("ファイルサイズ:" + file1.length() + "バイト");  // ファイルサイズ

		// ファイル名を変更 -------------------------------------------------------------------------------------------
		File file2 = new File(args[1]);
		boolean bln = file1.renameTo(file2);          // ファイル名を変更
		if (bln) {
			System.out.println("ファイル名を" + file1.getName() + "に変更しました。");
		} else {
			System.out.println("ファイル名を変更できませんでした。");
			System.exit(1);
		}
	}
}
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Sample extends JFrame {
	private JLabel lbl1, lbl2, lbl3, lbl4;
	private JPanel pnl1, pnl2;
	private JButton btn;

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	public Sample() {
		// タイトルの設定
		super("ファイル情報");

		// コンポーネント作成
		lbl1 = new JLabel("ボタンを押してください。");
		lbl2 = new JLabel();
		lbl3 = new JLabel();
		lbl4 = new JLabel();

		pnl1 = new JPanel();
		pnl2 = new JPanel();

		btn = new JButton("ファイル読込み");

		// ボタンに、アクションリスナーを設定
		btn.addActionListener(new MyActionListener());

		// パネルに、レイアウトマネージャーを設定
		pnl1.setLayout(new GridLayout(3, 1));

		// パネルに、コンポーネントを設定
		pnl1.add(lbl2);
		pnl1.add(lbl3);
		pnl1.add(lbl4);

		pnl2.add(btn);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl1, BorderLayout.NORTH);
		add(pnl1, BorderLayout.CENTER);
		add(pnl2, BorderLayout.SOUTH);
		
		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());
		// setDefaultCloseOperation(EXIT_ON_CLOSE);      // ウィンドウリスナーを設定するかわりに、これでも可
		
		// フレームの設定
		setSize(300, 300);
		setVisible(true);
	}

	private class MyWindowListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser fileChooser = new JFileChooser();                             // ファイルチューザーを使う
			int res = fileChooser.showOpenDialog(getContentPane());
			if (res == JFileChooser.APPROVE_OPTION) {
				// ラベルのテキスト変更
				lbl1.setText("ファイルを選択しました。");

				// ファイル情報の表示
				File selectedFile = fileChooser.getSelectedFile();
				lbl2.setText("ファイル名:" + selectedFile.getName());                 // ファイル名
				lbl3.setText("絶対パスは:" + selectedFile.getAbsolutePath());         // 絶対パス
				lbl4.setText("ファイルサイズ:" + selectedFile.length() + "バイト");   // ファイルサイズ
			} else if (res == JFileChooser.CANCEL_OPTION) {
				// ラベルのテキスト変更
				lbl1.setText("ファイル読込みをキャンセルしました。");
			}
		}
	}
}

< テキストファイルの読み書き >

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Sample extends JFrame {
	private JLabel lbl;
	private JPanel pnl;
	private JTextArea ta;
	private JScrollPane sp;
	private JButton btn1, btn2;

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	public Sample() {
		// タイトルの設定
		super("ファイルの読み書き");

		// コンポーネント作成
		lbl = new JLabel("ボタンを押してください。");
		pnl = new JPanel();
		btn1 = new JButton("ファイル読込み");
		btn2 = new JButton("ファイル書込み");
		ta = new JTextArea();
		sp = new JScrollPane(ta);

		// ボタンに、アクションリスナーを設定
		btn1.addActionListener(new MyActionListener());
		btn2.addActionListener(new MyActionListener());

		// パネルに、コンポーネントを設定
		pnl.add(btn1);
		pnl.add(btn2);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(sp, BorderLayout.CENTER);
		add(pnl, BorderLayout.SOUTH);
		

		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());
		// setDefaultCloseOperation(EXIT_ON_CLOSE);    // ウィンドウリスナーを設定するかわりに、これでも可

		// フレームの設定
		setSize(300, 300);
		setVisible(true);
	}

	private class MyWindowListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser fileChooser = new JFileChooser(); // ファイルチューザーを使う

			// ファイル読込みボタンの処理 -------------------------------------------------------------------
			if ((JButton) e.getSource() == btn1) {
				int res = fileChooser.showOpenDialog(getContentPane()); // オープンダイアログ
				if (res == JFileChooser.APPROVE_OPTION) {
					// ファイルの読込み
					File selectedFile = fileChooser.getSelectedFile();
					BufferedReader br;

					try {
						br = new BufferedReader(new FileReader(selectedFile));
						ta.read(br, null);
						br.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}

					// ラベルのテキスト変更
					lbl.setText("ファイルを読み込みました。");
				} else if (res == JFileChooser.CANCEL_OPTION) {
					// ラベルのテキスト変更
					lbl.setText("ファイル読込みをキャンセルしました。");
				}
			}

			// ファイル書込みボタンの処理 -------------------------------------------------------------------
			if ((JButton) e.getSource() == btn2) {
				int res = fileChooser.showSaveDialog(getContentPane()); // セーブダイアログ
				if (res == JFileChooser.APPROVE_OPTION) {
					// ファイルへの書込み
					File selectedFile = fileChooser.getSelectedFile();
					BufferedWriter bw;

					try {
						bw = new BufferedWriter(new FileWriter(selectedFile));
						ta.write(bw);
						bw.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}

					// ラベルのテキスト変更
					lbl.setText("ファイルへ書き込みました。");
				} else if (res == JFileChooser.CANCEL_OPTION) {
					// ラベルのテキスト変更
					lbl.setText("ファイル書込みをキャンセルしました。");
				}
			}
		}
	}
}

< バイナリファイルの読み書き >

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;

public class Sample extends JFrame {
	private JLabel lbl;
	private JPanel pnl1, pnl2;
	private JTextField[] tf = new JTextField[4];
	private JButton btn1, btn2;

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	public Sample() {
		// タイトルの設定
		super("バイナリファイルの読み書き");

		// コンポーネント作成
		lbl = new JLabel("ボタンを押してください。");
		pnl1 = new JPanel();
		pnl2 = new JPanel();
		btn1 = new JButton("バイナリファイル読込み");
		btn2 = new JButton("バイナリファイル書込み");
		for (int i = 0; i < tf.length; i++) {
			tf[i] = new JTextField(2);          // column数:2  ※表示幅を設定するだけで、文字数を制限するわけではない
		}

		// ボタンに、アクションリスナーを設定
		btn1.addActionListener(new MyActionListener());
		btn2.addActionListener(new MyActionListener());

		// パネルに、コンポーネントを設定
		for (int i = 0; i < tf.length; i++) {
			pnl1.add(tf[i]);
		}
		pnl2.add(btn1);
		pnl2.add(btn2);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl, BorderLayout.NORTH);
		add(pnl1, BorderLayout.CENTER);
		add(pnl2, BorderLayout.SOUTH);

		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());
		// setDefaultCloseOperation(EXIT_ON_CLOSE);       // ウィンドウリスナーを設定するかわりに、これでも可

		// フレームの設定
		pack();                // void java.awt.Window.pack() サブコンポーネントによってサイズを変更する
		setVisible(true);
	}

	private class MyWindowListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	/**
	 * バイナリファイルの読み書きをするクラス。
	 * 16進数2桁で読み書きするが、この例ではアルファベットは扱わない。
	 */
	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser fileChooser = new JFileChooser();                // ファイルチューザーを使う
			fileChooser.setFileFilter(new MyFileFilter());                // ファイルフィルタ

			// バイナリファイル読込みボタンの処理 --------------------------------------------------------
			if ((JButton) e.getSource() == btn1) {
				int res = fileChooser.showOpenDialog(getContentPane());   // オープンダイアログ
				if (res == JFileChooser.APPROVE_OPTION) {
					// バイナリファイルの読込み
					File selectedFile = fileChooser.getSelectedFile();
					BufferedInputStream bis;

					try {
						bis = new BufferedInputStream(new FileInputStream(selectedFile));
						for (int i = 0; i < tf.length; i++) {
							int num = bis.read();
							tf[i].setText(Integer.toString(num));
						}
						bis.close();
					} catch (Exception e1) {
						e1.printStackTrace();
					}

					// ラベルのテキスト変更
					lbl.setText("バイナリファイルを読み込みました。");
				} else if (res == JFileChooser.CANCEL_OPTION) {
					// ラベルのテキスト変更
					lbl.setText("バイナリファイル読込みをキャンセルしました。");
				}
			}

			// バイナリファイル書込みボタンの処理 --------------------------------------------------------
			if ((JButton) e.getSource() == btn2) {
				int res = fileChooser.showSaveDialog(getContentPane());   // セーブダイアログ
				if (res == JFileChooser.APPROVE_OPTION) {
					// バイナリファイルへの書込み
					File selectedFile = fileChooser.getSelectedFile();
					BufferedOutputStream bos;

					try {
						bos = new BufferedOutputStream(new FileOutputStream(selectedFile));
						for (int i = 0; i < tf.length; i++) {
							int num = Integer.parseInt(tf[i].getText());
							bos.write(num);
						}
						bos.close();
					} catch (Exception e1) {
						e1.printStackTrace();
					}

					// ラベルのテキスト変更
					lbl.setText("バイナリファイルへ書き込みました。");
				} else if (res == JFileChooser.CANCEL_OPTION) {
					// ラベルのテキスト変更
					lbl.setText("バイナリファイル書込みをキャンセルしました。");
				}
			}
		}
	}

	/**
	 * ファイルフィルタのクラス。javax.swing.filechooser.FileFilterクラスを拡張。
	 */
	private class MyFileFilter extends FileFilter {
		// このフィルタの説明
		@Override
		public String getDescription() {
			String str = "バイナリファイル";
			return str;
		}

		// このフィルタが指定されたファイルを受け付けるかどうかを返す
		@Override
		public boolean accept(File f) {
			if (f.isDirectory()) {
				return true;                 // ディレクトリであれば、trueを返す
			} else if (f.isFile()) {
				String fileName = f.getName();

				// ファイル名を全て小文字にして、指定された接尾辞で終わるかどうかをbooleanで返す
				if (fileName.toLowerCase().endsWith(".bin")) {
					return true;             // バイナリファイル(接尾辞が.bin)であれば、trueを返す
				}
			}
			return false;                    // ディレクトリでもバイナリファイルでもなければ、falseを返す
		}
	}
}

< ランダムアクセス >

  • ランダムアクセスファイルに対する読み取りと書き込みは、 java.io.RandomAccessFileクラスのインスタンスを利用する。
  • ファイルポインタ(ファイルの現在のオフセット)は、getFilePointerメソッドにより読み取ることができ、seekメソッドにより設定できる。
  • ランダムアクセス(ファイルの特定位置からのアクセス)
    ←→ シーケンシャルアクセス(ファイル先頭からのアクセス)
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.RandomAccessFile;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;

public class Sample extends JFrame {
	private JLabel lbl1, lbl2, lbl3;
	private JPanel pnl1, pnl2, pnl3, pnl4;
	private JTextField tf1, tf2;
	private JButton btn;

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	public Sample() {
		// タイトルの設定
		super("バイナリファイルの読み書き");

		// コンポーネント作成
		lbl1 = new JLabel("状況");
		lbl2 = new JLabel("読み込むデータの番号を入力してください。(1~5)");
		lbl3 = new JLabel("データ");
		tf1 = new JTextField(2);      // column数:2 ※表示幅を設定するだけで、文字数を制限するわけではない
		tf2 = new JTextField(2);
		pnl1 = new JPanel();
		pnl2 = new JPanel();
		pnl3 = new JPanel();
		pnl4 = new JPanel();
		btn = new JButton("バイナリデータ読込み");

		// ボタンに、アクションリスナーを設定
		btn.addActionListener(new MyActionListener());

		// パネルに、レイアウトマネージャーを設定
		pnl1.setLayout(new GridLayout(4, 1));

		// パネルに、コンポーネントを設定
		pnl2.add(tf1);                // テキストフィールドが横幅いっぱいに広がらないように、いったんパネルに配置する
		pnl3.add(tf2);

		pnl1.add(lbl2);
		pnl1.add(pnl2);
		pnl1.add(lbl3);
		pnl1.add(pnl3);

		pnl4.add(btn);

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(lbl1, BorderLayout.NORTH);
		add(pnl1, BorderLayout.CENTER);
		add(pnl4, BorderLayout.SOUTH);

		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());
		// setDefaultCloseOperation(EXIT_ON_CLOSE);     // ウィンドウリスナーを設定するかわりに、これでも可

		// フレームの設定
		pack();                      // void java.awt.Window.pack() サブコンポーネントによってサイズを変更する
		setVisible(true);
	}

	private class MyWindowListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	/**
	 * バイナリファイルの読み書きをするクラス。 16進数2桁で読み書きするが、この例ではアルファベットは扱わない。
	 */
	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser fileChooser = new JFileChooser();             // ファイルチューザーを使う
			fileChooser.setFileFilter(new MyFileFilter());             // ファイルフィルタ

			// バイナリファイル読込みボタンの処理 -------------------------------------------------------------
			int res = fileChooser.showOpenDialog(getContentPane());    // オープンダイアログ
			if (res == JFileChooser.APPROVE_OPTION) {
				// バイナリファイルの読込み
				File selectedFile = fileChooser.getSelectedFile();
				RandomAccessFile raf;

				try {
					raf = new RandomAccessFile(selectedFile, "r");
					int pos = Integer.parseInt(tf1.getText());
					raf.seek(pos - 1);                                 // 読込み開始位置を移動
					int num = raf.read();
					tf2.setText(Integer.toString(num));
					raf.close();
				} catch (Exception e1) {
					e1.printStackTrace();
				}

				// ラベルのテキスト変更
				lbl1.setText("バイナリデータを読み込みました。");
			} else if (res == JFileChooser.CANCEL_OPTION) {
				// ラベルのテキスト変更
				lbl1.setText("バイナリデータ読込みをキャンセルしました。");
			}
		}
	}

	/**
	 * ファイルフィルタのクラス。javax.swing.filechooser.FileFilterクラスを拡張。
	 */
	private class MyFileFilter extends FileFilter {
		// このフィルタの説明
		@Override
		public String getDescription() {
			String str = "バイナリファイル";
			return str;
		}

		// このフィルタが指定されたファイルを受け付けるかどうかを返す
		@Override
		public boolean accept(File f) {
			if (f.isDirectory()) {
				return true;                     // ディレクトリであれば、trueを返す
			} else if (f.isFile()) {
				String fileName = f.getName();

				// ファイル名を全て小文字にして、指定された接尾辞で終わるかどうかをbooleanで返す
				if (fileName.toLowerCase().endsWith(".bin")) {
					return true;                 // バイナリファイル(接尾辞が.bin)であれば、trueを返す
				}
			}
			return false;                        // ディレクトリでもバイナリファイルでもなければ、falseを返す
		}
	}
}

ウィンドウアプリケーション ※応用

  • オブジェクトの入出力には、java.io.ObjectInputStreamクラス(入力)と、java.io.ObjectInputStreamクラス(出力)が利用できる。
  • オブジェクトの入出力では、java.io.Serializable インタフェースを実装することで、クラスの直列化可能性を有効にする必要がある。
  • 色選択のダイアログを扱うには、Swingのカラーチューザー(javax.swing.JColorChooserクラス)が使用できる。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.filechooser.FileFilter;

// クラスの直列化可能性は、java.io.Serializable インタフェースを実装するクラスによって有効になる
abstract class Shape implements Serializable {        // シリアライズ可能にする
	public static final int RECT = 0;
	public static final int OVAL = 1;
	public static final int LINE = 2;

	protected int x1, y1, x2, y2;
	protected Color c;

	abstract public void draw(Graphics g);

	public void setColor(Color c) {
		this.c = c;
	}

	public void setStartPoint(int x, int y) {
		x1 = x;
		y1 = y;
	}

	public void setEndPoint(int x, int y) {
		x2 = x;
		y2 = y;
	}
}

class Rect extends Shape {
	public void draw(Graphics g) {
		g.setColor(c);
		g.fillRect(x1, y1, x2 - x1, y2 - y1);
	}
}

class Oval extends Shape {
	public void draw(Graphics g) {
		g.setColor(c);
		g.fillOval(x1, y1, x2 - x1, y2 - y1);
	}
}

class Line extends Shape {
	public void draw(Graphics g) {
		g.setColor(c);
		g.drawLine(x1, y1, x2, y2);
	}
}

public class Sample extends JFrame {
	private JLabel lbl;
	private JMenuBar mb;
	private JMenu[] menu = new JMenu[3];
	private JMenuItem[] mi = new JMenuItem[6];
	private ButtonGroup bg;
	private MyJPanel myPnl;                 // 自作パネル(JPanelのサブクラス)

	private Color currentColor;
	private int currentShape;

	private ArrayList<Shape> shapeList;     // 非同期の、オブジェクトの可変長配列

	public static void main(String[] args) {
		Sample sample = new Sample();
	}

	public Sample() {
		// タイトルの設定
		super("サンプルアプリケーション");

		// コンポーネントの作成
		lbl = new JLabel("四角形が選択されています。");
		menu[0] = new JMenu("ファイル");
		menu[1] = new JMenu("設定");
		menu[2] = new JMenu("図形");

		mi[0] = new JMenuItem("開く");
		mi[1] = new JMenuItem("保存");
		mi[2] = new JRadioButtonMenuItem("四角形");
		mi[3] = new JRadioButtonMenuItem("楕円形");
		mi[4] = new JRadioButtonMenuItem("直線");
		mi[5] = new JMenuItem("色");

		myPnl = new MyJPanel(); // 自作パネル

		// コンテナに、コンポーネントを設定
		menu[0].add(mi[0]);
		menu[0].add(mi[1]);

		menu[1].add(menu[2]);
		menu[1].add(mi[5]);

		menu[2].add(mi[2]);
		menu[2].add(mi[3]);
		menu[2].add(mi[4]);

		// メニューバーに、メニューを設定
		mb = new JMenuBar();
		mb.add(menu[0]);
		mb.add(menu[1]);

		// ラジオボタンメニューアイテムを、ボタングループに設定
		bg = new ButtonGroup();
		bg.add(mi[2]);
		bg.add(mi[3]);
		bg.add(mi[4]);

		// メニューアイテムに、アクションリスナーを設定
		for (int i = 0; i < mi.length; i++) {
			mi[i].addActionListener(new MyActionListener());
		}

		// コンテントペインに、レイアウトマネージャーを設定
		setLayout(new BorderLayout());

		// コンテントペインに、コンポーネントを設定
		add(mb, BorderLayout.NORTH);
		add(myPnl, BorderLayout.CENTER);
		add(lbl, BorderLayout.SOUTH);

		// 初期化
		currentColor = Color.BLACK;
		currentShape = Shape.RECT;
		mi[2].setSelected(true);
		shapeList = new ArrayList<Shape>();

		// フレームに、ウィンドウリスナーを設定
		addWindowListener(new MyWindowListener());
		// setDefaultCloseOperation(EXIT_ON_CLOSE);    // ウィンドウリスナーのかわりに、これでも可

		// フレームの設定
		setSize(300, 300);
		setVisible(true);
	}

	private class MyJPanel extends JPanel {
		public MyJPanel() {
			setOpaque(false);
			// パネルにマウスリスナーを設定
			addMouseListener(new MyMouseListener());
		}

		@Override
		public void paint(Graphics g) {
			for (int i = 0; i < shapeList.size(); i++) {
				Shape shape = shapeList.get(i);
				shape.draw(g);
			}
		}

		private class MyMouseListener extends MouseAdapter {
			@Override
			public void mousePressed(MouseEvent e) {
				Shape shape = null;
				if (currentShape == Shape.RECT) {
					shape = new Rect();
				} else if (currentShape == Shape.OVAL) {
					shape = new Oval();
				} else if (currentShape == Shape.LINE) {
					shape = new Line();
				}
				shape.setColor(currentColor);
				shape.setStartPoint(e.getX(), e.getY());
				shape.setEndPoint(e.getX(), e.getY());
				shapeList.add(shape);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				Shape shape = shapeList.get(shapeList.size() - 1);
				shape.setEndPoint(e.getX(), e.getY());
				repaint();                                            // 再描画
			}

		}
	}

	private class MyWindowListener extends WindowAdapter {
		@Override
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	private class MyActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JMenuItem localMi = (JMenuItem) e.getSource();

			if (localMi == mi[0] || localMi == mi[1]) {
				JFileChooser fc = new JFileChooser();       // ファイルチューザーを利用
				fc.setFileFilter(new MyFileFilter());

				// 読み込み
				if (localMi == mi[0]) {
					int res = fc.showOpenDialog(getContentPane());
					if (res == JFileChooser.APPROVE_OPTION) {
						File file = fc.getSelectedFile();
						try {
							FileInputStream fis = new FileInputStream(file);
							ObjectInputStream ois = new ObjectInputStream(fis);

							shapeList.clear();
							Shape localShape = null;

							while (fis.available() > 0) {
								localShape = (Shape) ois.readObject();
								shapeList.add(localShape);
							}

							ois.close();
						} catch (Exception e1) {
							e1.printStackTrace();
						}

						repaint(); // 再描画
						lbl.setText("ファイルを開きました。");
					} else if (res == JFileChooser.CANCEL_OPTION) {
						lbl.setText("ファイルを開くのを、キャンセルしました。");
					}

				// 書き出し
				} else if (localMi == mi[1]) {
					int res = fc.showSaveDialog(getContentPane());
					if (res == JFileChooser.APPROVE_OPTION) {
						File file = fc.getSelectedFile();
						ObjectOutputStream oos;
						try {
							oos = new ObjectOutputStream(new FileOutputStream(file));
							for (int i = 0; i < shapeList.size(); i++) {
								oos.writeObject(shapeList.get(i));
							}
							oos.close();
						} catch (Exception e1) {
							e1.printStackTrace();
						}
						lbl.setText("ファイルを保存しました。");
					} else if (res == JFileChooser.CANCEL_OPTION) {
						lbl.setText("ファイルを保存するのを、キャンセルしました。");
					}
				}

			} else if (localMi == mi[2]) {
				currentShape = Shape.RECT;
				lbl.setText("四角形を選択しました。");
			} else if (localMi == mi[3]) {
				currentShape = Shape.OVAL;
				lbl.setText("楕円形を選択しました。");
			} else if (localMi == mi[4]) {
				currentShape = Shape.LINE;
				lbl.setText("直線を選択しました。");
			} else if (localMi == mi[5]) {
				// カラーチューザーを利用
				Color res = JColorChooser.showDialog(getContentPane(), "色選択ダイアログ", Color.BLACK);
				if (res != null) {
					currentColor = res;
					lbl.setText("色を選択しました。");
				} else {
					lbl.setText("色の選択をキャンセルしました。");
				}
			}
		}

		private class MyFileFilter extends FileFilter {
			@Override
			public boolean accept(File f) {
				if (f.isDirectory()) {
					return true;
				} else if (f.isFile()) {
					String fileName = f.getName();
					if (fileName.toLowerCase().endsWith(".go")) {
						return true;
					}
				}
				return false;
			}

			@Override
			public String getDescription() {
				return "グラフィックオブジェクトファイル";
			}
		}
	}
}

この辺で一旦終了。

~旦(´・ω・`)もぅ疲れたよパトラッシュ・・・。お茶ずずず・・・





コメントの投稿

非公開コメント

マイブログへようこそ♪
PLEASANT_DRAGON

2DCG&3DCG,プログラミング,
日記などを掲載中☆

(*´▽`*)コメント大歓迎です☆

最新記事
記事一覧

全ての記事を表示する

カテゴリ
SAI (0)
mi (2)
C (1)
C++ (1)
C# (0)
VBA (0)
月別アーカイブ
最新コメント
RSSリンクの表示
リンク
FC2ブログランキング

FC2Blog Ranking

ピックアップ商品1♪










カレンダー
06 | 2017/07 | 08
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
ブログ内検索フォーム
プロフィール

エクレア

Author:エクレア


  • 2DCG&3DCGの創作活動をしています。

  • SF系のメカが大好物。

アクセスカウンター
Twitter
ピックアップ商品2♪