プラグイン可能なルックアンドフィール

目 次
はじめに
21
Part 1
●
Swingの基本構造
Chapter 1
概要
30
32
1.1 Swing の歴史
1.2 軽量コンポーネントと重量コンポーネント
33
1.3 Swing コンポーネント
34
1.3.1 AWT を置き換えるコンポーネント
1.3.2 Swing の追加コンポーネント
33
35
1.4 ユーザーインターフェイスコンポーネント
35
1.4.1 プラグイン可能なルックアンドフィール
37
38
1.5 Swing パッケージの概要
40
1.6 Swing と AWT
1.6.1 ピアとプラグイン可能なルックアンドフィール
1.7 Swing の実行
41
1.7.1 Web ブラウザにおける Swing の使用
1.8 Swing に関する情報
45
1.9 まとめ
44
42
41
8
目 次
Chapter 2
Swing の基礎
48
49
2.1 アプレットとアプリケーション
50
2.1.1 アプレット
51
2.1.2 JApplet クラス
55
2.1.3 アプリケーション
56
2.1.4 JFrame クラス
59
2.1.5 アプレットとアプリケーションの組み合わせ
2.2 GJApp クラス
60
2.3 Swing コンポーネントと AWT コンポーネントの混在
64
2.3.1 Z オーダー
68
2.3.2 Swing のポップアップメニュー
71
2.3.3 スクロール
73
2.3.4 内部フレーム
76
2.4 Swing とスレッド
2.4.1 Swing におけるシングルスレッドの設計
76
77
2.4.2 SwingUtilities クラスのメソッド
2.5 まとめ
64
85
Chapter 3
Swing コンポーネントのアーキテクチャ
89
3.1 MVC アーキテクチャ
3.1.1 プラグイン可能なビューとコントローラ
90
3.1.2 ビューの更新
3.2 Swing の MVC
92
3.2.1 Swing コンポーネント
93
3.2.2 Swing コンポーネントの構成
95
3.2.3 Swing コンポーネントの動作
96
3.2.4 モデル
3.2.5 UI の委譲先
100
112
3.2.6 コンポーネントと UI の委譲先
3.2.7 リスナー
3.3 まとめ
130
125
113
90
88
9
目 次
Chapter 4
JComponent クラス
132
133
4.1 JComponent クラスの概要
4.1.1 ボーダー
134
134
4.1.2 ユーザー補助機能のサポート
135
4.1.3 ダブルバッファリング
135
4.1.4 グラフィックスのデバッグ
137
4.1.5 自動スクロール
4.1.6 ツールチップ
137
138
4.1.7 キー入力処理とクライアントプロパティ
4.2 JComponent クラス
138
139
4.2.1 AWT コンテナとしての Swing コンポーネント
140
4.2.2 最小サイズ、最大サイズ、推奨サイズ
144
4.3 JComponent のレンダリング
145
4.3.1 Swing コンポーネントにおける描画処理のカスタマイズ
145
4.3.2 AWT コンポーネントにおける描画メソッドのオーバーライド
4.3.3 Swing コンポーネントにおける描画メソッドのオーバーライド
4.3.4 paint( )、repaint( )、update( )
149
150
4.3.5 validate( )、invalidate( )、revalidate( )
151
4.3.6 不透明なコンポーネントと透明なコンポーネント
4.3.7 Swing コンポーネントの即時描画
4.4 ダブルバッファリング
154
156
160
4.4.1 カスタムコンポーネントにおけるダブルバッファリング
4.5 グラフィックスのデバッグ
169
4.6 自動スクロール
164
4.6.1 カスタムコンポーネントにおける自動スクロール
175
4.7.1 マウスの位置に対応するツールチップ
170
4.7 ツールチップ
4.7.2 ツールチップの推奨位置
177
179
4.7.3 ツールチップの動作のカスタマイズ
180
181
4.7.4 ツールチップのルックアンドフィールのカスタマイズ
182
4.8 キー入力処理
187
4.9 クライアントプロパティ
191
4.10 フォーカスの管理
4.10.1 JComponent のフォーカス関連のプロパティ
4.10.2 フォーカスマネージャ
194
191
147
10
目 次
196
4.11 ユーザー補助機能
199
4.12 まとめ
Chapter 5
ボーダー、アイコン、アクション
201
5.1 ボーダー
202
5.1.1 ボーダーとインセット
203
5.1.2 Swing のボーダー
208
5.1.3 不透明なボーダーと透明なボーダー
210
5.1.4 javax.swing.border パッケージ
210
5.1.5 Border インターフェイス
211
5.1.6 AbstractBorder クラス
5.1.7 ボーダーファクトリ( ボーダーの共有)
212
213
5.1.8 組み込みのボーダーの置き換え
214
5.1.9 ボーダーのカスタマイズ
216
5.2 アイコン
219
5.2.1 アイコンとコンポーネント
5.2.2 アイコンの共有
220
224
5.2.3 画像アイコン
227
5.2.4 アニメーションの画像アイコン
228
5.3 アクション
5.3.1 アクションによる操作の制御
231
235
5.3.2 Action の定数
5.4 まとめ
200
238
Chapter 6
ユーティリティ
6.1 タイマー
240
241
243
6.1.1 Timer クラス
6.2 イベントリスナーリスト
249
251
6.2.1 EventListenerList クラス
6.3 Swing のユーティリティ
6.4 Swing の定数
252
260
6.5 BoxLayout クラスと Box クラス
260
目 次
261
6.5.1 BoxLayout クラス
263
6.5.2 Box クラス
267
6.6 進捗モニタ
267
6.6.1 ProgressMonitor クラス
6.6.2 ProgressMonitorInputStream クラス
273
276
6.7 元に戻す/やり直し
278
6.7.1 元に戻す/やり直しの実装
282
6.7.2 UndoableEditSupport クラス
285
6.7.3 CompoundEdit クラス
290
6.7.4 UndoManager クラス
291
6.7.5 StateEdit クラス
6.8 まとめ
11
296
Chapter 7
プラグイン可能なルックアンドフィール
299
7.1 ルックアンドフィールのアーキテクチャ
301
7.1.1 ルックアンドフィール
308
7.1.2 ルックアンドフィールのデフォルト値
312
7.1.3 UIManager クラス
318
7.1.4 UIResource インターフェイス
7.2 Java のルックアンドフィール
327
329
7.3 補助的な UI
7.4 まとめ
322
322
7.2.1 クライアントプロパティ
7.2.2 テーマ
298
332
Part 2
●
Swingコンポーネント
Chapter 8
ラベルとボタン
334
8.1 JLabel クラスと JButton クラス
8.2 JLabel クラス
337
335
12
目 次
349
8.2.1 JLabel のプロパティ
350
8.2.2 JLabel のイベント
350
8.2.3 JLabel の概要
8.3 ボタン
354
355
8.3.1 ボタンの階層
355
8.4 JButton クラス
359
8.4.1 JButton のプロパティ
362
8.4.2 JButton のイベント
366
8.4.3 JButton の概要
380
8.4.4 AWT との互換性
8.5 まとめ
380
Chapter 9
トグルボタン、チェックボックス、
ラジオボタン
9.1 トグルボタン
383
384
9.1.1 JToggleButton のプロパティ
384
9.1.2 JToggleButton のイベント
387
9.1.3 JToggleButton の概要
389
9.1.4 AWT との互換性
9.2 ボタングループ
389
391
9.3 チェックボックス
394
9.3.1 JCheckBox のプロパティ
394
9.3.2 JCheckBox のイベント
394
9.3.3 JCheckBox の概要
9.3.4 AWT との互換性
9.4 ラジオボタン
397
397
401
9.4.1 JRadioButton のプロパティ
401
9.4.2 JRadioButton のイベント
401
9.4.3 JRadioButton の概要
9.4.4 AWT との互換性
9.5 まとめ
404
403
382
目 次
13
Chapter 10
メニューとツールバー
406
408
10.1 メニュー、メニューバー、ツールバー
412
10.2 メニューとポップアップメニュー
414
10.3 JMenuItem クラス
10.3.1 メニュー項目のアクセラレータとショートカット
420
10.3.2 JMenuItem のプロパティ
420
10.3.3 JMenuItem のイベント
424
10.3.4 JMenuItem の概要
427
10.3.5 AWT との互換性
428
10.4 JCheckBoxMenuItem クラス
430
10.4.1 JCheckBoxMenuItem のプロパティ
430
10.4.2 JCheckBoxMenuItem のイベント
431
10.4.3 JCheckBoxMenuItem の概要
433
10.4.4 AWT との互換性
433
10.5 JRadioButtonMenuItem クラス
435
10.5.1 JRadioButtonMenuItem のプロパティ
435
10.5.2 JRadioButtonMenuItem のイベント
440
10.5.3 JRadioButtonMenuItem の概要
441
10.5.4 AWT との互換性
10.6 JMenu クラス
441
443
10.6.1 メニューの動的な変更
447
10.6.2 プルライトメニュー
450
10.6.3 JMenu のプロパティ
451
10.6.4 JMenu のイベント
10.6.5 JMenu の概要
453
10.6.6 AWT との互換性
460
461
10.7 MenuElement インターフェイス
462
10.7.1 MenuElement の実装
10.8 JPopupMenu クラス
467
10.8.1 ポップアップトリガー
469
471
10.8.2 さまざまなポップアップメニュー
472
10.8.3 ポップアップメニューの起動元
476
10.8.4 JPopupMenu のプロパティ
477
10.8.5 JPopupMenu のイベント
10.8.6 JPopupMenu の概要
479
417
14
目 次
484
10.8.7 AWT との互換性
485
10.9 JMenuBar クラス
486
10.9.1 メニューバーのメニューとコンポーネント
491
10.9.2 JMenuBar のプロパティ
492
10.9.3 JMenuBar のイベント
492
10.9.4 JMenuBar の概要
494
10.9.5 AWT との互換性
494
10.10 JToolBar クラス
499
10.10.1 ツールバーのロールオーバー
500
10.10.2 ツールバーとアクション
502
10.10.3 ツールバーのフローティング
10.10.4 ツールバーのボタンとツールチップ
505
10.10.5 JToolBar のプロパティ
506
10.10.6 JToolBar のイベント
10.10.7 JToolBar の概要
506
10.10.8 AWT との互換性
508
10.11 まとめ
503
508
Chapter 11
進捗バー、スライダー、セパレータ
511
11.1 JProgressBar クラス
513
11.1.1 進捗バーとスレッド
518
11.1.2 JProgressBar のプロパティ
519
11.1.3 JProgressBar のイベント
521
11.1.4 JProgressBar の概要
523
11.1.5 AWT との互換性
11.2 JSlider クラス
523
524
11.2.1 色が塗られたスライダー
11.2.2 スライダーの目盛り
525
11.2.3 スライダーのラベル
529
11.2.4 スライダーの値の反転
531
11.2.5 スライダーの拡張範囲
532
536
11.2.6 JSlider のプロパティ
537
11.2.7 JSlider のイベント
11.2.8 JSlider の概要
11.2.9 AWT との互換性
538
541
510
目 次
541
11.3 JSeparator クラス
544
11.3.1 セパレータとボックス
547
11.3.2 JSeparator のプロパティ
547
11.3.3 JSeparator のイベント
547
11.3.4 JSeparator の概要
548
11.3.5 AWT との互換性
11.4 まとめ
15
548
Chapter 12
軽量コンテナ
12.1 JPanel クラス
550
552
554
12.1.1 JPanel のプロパティ
554
12.1.2 JPanel のイベント
555
12.1.3 JPanel の概要
555
12.1.4 AWT との互換性
556
12.2 JRootPane クラス
556
12.2.1 RootPaneContainer インターフェイス
558
12.2.2 ガラスペイン
561
12.2.3 コンテンツペイン
566
12.2.4 JRootPane のプロパティ
567
12.2.5 JRootPane のイベント
571
12.2.6 JRootPane の概要
573
12.2.7 AWT との互換性
573
12.3 JLayeredPane クラス
575
12.3.1 軽量コンポーネントの Z オーダー
12.3.2 層の割り当て
576
579
12.3.3 同一層の複数のコンポーネント
12.3.4 ドラッグ層
583
588
12.3.5 JLayeredPane のプロパティ
589
12.3.6 JLayeredPane の概要
592
12.3.7 AWT との互換性
592
12.4 JTabbedPane クラス
12.4.1 タブの位置
594
599
12.4.2 JTabbedPane のプロパティ
601
12.4.3 JTabbedPane のイベント
12.4.4 JTabbedPane の概要
602
16
目 次
605
12.5 JSplitPane クラス
611
12.5.1 JSplitPane のプロパティ
612
12.5.2 JSplitPane のイベント
613
12.5.3 JSplitPane の概要
616
12.5.4 AWT との互換性
12.6 まとめ
616
Chapter 13
スクロール
618
13.1 JViewport クラス
619
623
13.1.1 ビューポートのビューのドラッグ
13.1.2 scrollRectToVisible( )
625
13.1.3 JViewport のプロパティ
629
630
13.1.4 JViewport のイベント
633
13.1.5 JViewport の概要
637
13.1.6 AWT との互換性
637
13.2 JScrollPane クラス
13.2.1 スクロールペインのヘッダー
639
13.2.2 スクロールペインのコーナー
645
648
13.2.3 JScrollPane のプロパティ
650
13.2.4 JScrollPane のイベント
650
13.2.5 JScrollPane の概要
656
13.2.6 AWT との互換性
657
13.3 Scrollable インターフェイス
13.4 JScrollBar クラス
660
13.4.1 JScrollBar クラスによる手動スクロール
13.4.2 ブロック増分値とユニット増分値
670
13.4.3 JScrollBar のプロパティ
671
13.4.4 JScrollBar のイベント
13.4.5 JScrollBar の概要
13.4.6 AWT との互換性
13.5 まとめ
索 引
679
676
673
675
665
661
CHAPTER
1
Swing の歴史
軽量コンポーネントと重量コンポーネント
Swing コンポーネント
- AWT を置き換えるコンポーネント
- Swing の追加コンポーネント
ユーザーインターフェイスコンポーネント
- プラグイン可能なルックアンドフィール
Swing パッケージの概要
Swing と AWT
- ピアとプラグイン可能なルックアンドフィール
Swing の実行
- Web ブラウザにおける Swing の使用
Swing に関する情報
まとめ
概要
JFC( Java Foundation Class )は GUI を開発するための API の集合で、次の API を含む。
●
AWT( Abstract Window Toolkit )1.1 以降
●
2D API
●
Swing コンポーネント
●
Accessibility API
AWT は、Java の GUI の開発用に作られた最初のツールキットで、JFC の基盤を提供する。
AWT については『グラフィック Java2 』の Vol.1 で詳しく解説している。
2D API は、AWT では不十分な画像処理の追加機能を提供する。たとえば、AWT では画像
を生成する際に 1 ピクセル四方のペンだけを提供しているが、2D API では任意の太さのペン
を提供するなど、2 次元の描画機能を数多く備えている。2D API については、『グラフィック
Java2 』の Vol.3 で詳しく解説する。
Swing は、ほとんどが AWT 上に構築される軽量コンポーネント*1 から構成される。Swing
は、AWT には含まれない数多くの追加コンポーネントの他に、AWT の重量コンポーネント
を置き換える軽量コンポーネントを提供する。また、プラグイン可能なルックアンドフィール
などの機能を含め、GUI を実装するための魅力的な基本構造を提供する。そのため、Swing コ
ンポーネントは、さまざまなプラットフォームに合わせてルックアンドフィールを変更できる。
その他にも、ダブルバッファリング、グラフィックスのデバッグ、テキスト編集などの基本機能
が提供されている。
*1 軽量コンポーネントと重量コンポーネントの詳細については、「軽量コンポーネントと重量コンポーネン
ト」を参照。
32
Chapter 1 概要
Accessibility API は、Swing コンポーネントと障害者のサポート技術を結ぶクラスの集合で
ある。JFC は他にも、Accessibility API と連動する数多くのアクセスツールを備えている。
1.1 Swingの歴史
Swing を理解するには、最初に基本構造である AWT を理解しなければならない。
Java は信じられないような速さで実用化され、Java で最もグラフィカルな API である AWT
は突如として注目の的となった。しかし、残念ながら AWT はその注目にこたえられるほど準
備が整っていなかった。
AWT の最初のバージョンは、50 万人以上の Java 開発者が利用する強力なユーザーインター
フェイスツールキットとして設計されていなかった。簡単なアプレットの単純なユーザーイン
ターフェイスの開発をサポートするにすぎなかったのである。たとえば、最初の AWT にはオ
ブジェクト指向のユーザーインターフェイスツールキットに要求されるクリップボード、印刷
のサポート、キーボードのナビゲーションなどの機能の多くが含まれていなかった。さらに、
ポップアップメニューやスクロールペインといった最新のユーザーインターフェイスの開発で
最重要とみなされるべき基本機能さえ提供されていなかった。
また、AWT の基本構造は大きな問題を抱えていた。AWT が採用していた継承ベースのイ
ベントモデルはプログラムを肥大化させる原因となり、さらにピアベースの設計は AWT のア
キレス腱になった。
開発を急ぎ、ネイティブなルックアンドフィールに固執したことにより、ピアベースの設計を
余儀なくされ、結果として失敗につながった。ピアはネイティブのユーザーインターフェイス
コンポーネントで、非常に薄い AWT オブジェクトから作業を委譲される。ピアは、ピア自体
の描画やイベントの処理などの詳細な作業をすべて行うため、AWT コンポーネントは必要に
応じてピアとの通信を行うだけで済む。AWT クラス群は複雑なネイティブピアの周囲に取り
付けられた単純な枠にすぎないため、AWT の最初の開発チームは驚異的な速さ*2 でコンポー
ネントを開発することができた。たとえば、java.awt.Panel クラスのコードは、わずか 20 行
ほどである。
ただし、ピアによる設計思想はその重大な短所をさらけ出すことになった。まず、ほとんど
のプラットフォーム上でピアはネイティブなウィンドウにレンダリングされる。1 つのネイティ
ブウィンドウに 1 つのコンポーネントという比率が必ずしも高いパフォーマンスを実現する基
準であるとは限らず、多くの AWT コンポーネントを含むアプレットはパフォーマンスを犠牲
にすることになった。
また、異なるプラットフォームのネイティブなピアを Java の 1 つのフレームワークとして利
用するというのも問題である。この方法により異なるプラットフォームで AWT コンポーネン
トの動作を一貫させるのは実際には不可能だ。結果として、必要な新しいコンポーネントを実
装する以前に、ピアのバグと互換性の問題を解決するために多くの時間が浪費された。
*2 AWT の最初のバージョンは 6 週間という短い期間で開発された。
1.3 Swing コンポーネント
33
さらに、AWT は多くのバグを抱えていた。そのため、サードパーティは AWT より豊富な
機能を持ち、より信頼性の高い基本構造を持つ独自のツールキットを提供し始めた。例として
Netscape の IFC( Internet Foundation Class )がある。これは、NEXTSTEP のユーザーイン
ターフェイスツールキットの概念に基づく軽量クラスの集合である。IFC はピアに依存せず、
AWT のコンポーネントと比べるとさまざまな利点があり、ユーザーのシェアを伸ばし始めた。
Java のコミュニティが 2 つのユーザーインターフェイスツールキットに分断されようとして
いる事態に対し、JavaSoft は Netscape と交渉して JFC を実装した( Apple と IBM も JFC の
開発に参画した)
。Netscape の開発者は Swing の技術者と協力し、IFC の機能の多くを Swing
コンポーネントに組み込んだ。
当初、Swing は Netscape の IFC と非常に似たものになる予定であった。しかし、時の経過
と共にプラグイン可能なルックアンドフィールなどの機能が追加され、設計が大きく変更され
て、最初の考えとは大幅に異なるものになった。Swing には IFC の技術が非常に多く組み込ま
れてはいるが、Swing 1.0 がリリースされる時点では IFC との外見的な類似性はほとんど失わ
れている。現在、Swing は AWT と IFC の最も優れた部分を包括的なユーザーインターフェイ
スツールキットとして提供している。
1.2 軽量コンポーネントと重量コンポーネント
軽量コンポーネントは AWT 1.1 で初めて導入された。AWT は当初ネイティブなピアコン
ポーネントに関連付けられた重量コンポーネントだけを提供しており、この重量コンポーネン
トはネイティブシステムの不透明なウィンドウでレンダリングされる。
一方、軽量コンポーネントはネイティブなピアを持たず、重量コンテナのウィンドウでレン
ダリングされる。
軽量コンポーネントはネイティブシステムの不透明なウィンドウでレンダリングされないた
め、透明な背景を持つことができる。軽量および重量コンポーネントは矩形の境界を持つが、
軽量コンポーネントは透明な背景を持つことにより境界を矩形以外に見せることができる。
ほとんどの Swing コンポーネントは軽量コンポーネントである。唯一の例外は Swing の最上
位コンテナであるフレーム、アプレット、ウィンドウ、ダイアログだ。軽量コンポーネントは、
コンポーネントそのもののウィンドウではなくそれを含むコンテナのウィンドウでレンダリング
されるため、最終的には重量コンテナに含まれていなければならない。したがって、Swing の
フレーム、アプレット、ダイアログは、軽量の Swing コンポーネントをレンダリングするウィ
ンドウを提供するために重量コンポーネントになる。
1.3 Swingコンポーネント
Swing にはコンポーネントやサポートクラスなど 250 以上のクラスがあり、AWT コンポー
ネントの約 4 倍に相当する 40 以上のコンポーネントを提供する。Swing は、AWT の重量コ
ンポーネントを置き換える軽量コンポーネントだけでなく、GUI の開発を容易にする数多くの
追加コンポーネントを提供している。
34
Chapter 1 概要
1.3.1 AWTを置き換えるコンポーネント
図 1-1 に、AWT の重量コンポーネントを置き換える Swing の軽量コンポーネントを示す。
図 1-1 のコンポーネントの多くは対応する AWT コンポーネントのソースコードとほぼ互換性
を持ち、AWT コンポーネントを既存のコードのまま簡単に置き換えることができる。
AWT を置き換える Swing コンポーネントの多くは、AWT コンポーネントと同様の機能だ
けでなく、追加機能を提供する。たとえば、AWT のボタンとラベルはテキストの表示だけを
行うが、Swing のボタンとラベルはアイコンとテキストを表示できる。
図 1-1 のコンポーネントはすべて Windows のルックアンドフィールを持つ。
図 1-1 AWT を置き換える Swing コンポーネント ―(左上から時計回りに)ボタン/ラジオボタン/チェックボックス、ラ
ベル、スクロールバー、テキストフィールド/テキスト領域、スクロールペイン、リスト、ポップアップメニュー、
メニューバー/メニュー、コンボボックス
1.4 ユーザーインターフェイスコンポーネント
35
1.3.2 Swingの追加コンポーネント
Swing は、AWT の重量コンポーネントを置き換えるコンポーネントに加え、数多くの追加
コンポーネントを提供する。図 1-2 に、テーブル、ツリー、カスタムダイアログなどの Swing
の追加コンポーネントを示す。
図 1-2 Swing の追加コンポーネント―(左上から時計回りに)内部フレーム、タブペイン、ツールバー、カラーチューザ、
テーブル、ツリー、ダイアログボックス
1.4 ユーザーインターフェイスコンポーネント
Swing には 250 以上のクラスがあり、主にユーザーインターフェイスコンポーネントとサ
ポートクラスに分けられる。ユーザーインターフェイスコンポーネントとサポートクラスを区
別するため、Swing のコンポーネントは J で始まる。表 1-1 に、Swing が提供するユーザーイ
36
Chapter 1 概要
ンターフェイスコンポーネントをまとめる。AWT コンポーネントを置き換えるものは斜体で
示す。
表 1-1 Swing のユーザーインターフェイスコンポーネント
コンポーネントクラス
説明
JApplet
java.applet.Applet の拡張クラス( JRootPane のインスタンスを含む)
JButton
テキストとグラフィックスを表示するボタン( AWT のボタンを置き換える)
JCheckBox
テキストとグラフィックスを表示するチェックボックス( AWT の選択を置き換える)
JCheckBoxMenuItem
チェックボックスメニュー項目( AWT のチェックボックスメニュー項目を置き換え
る)
JComboBox
ドロップダウンリストを持つテキストフィールド( AWT の選択を置き換える)
JComponent
すべての軽量コンポーネントの基本クラス
JDesktopPane
内部フレームのコンテナ
JDialog
Swing ダイアログの基本クラス( AWT の Dialog クラスを拡張する)
JEditorPane
テキストを編集するためのテキストペイン
JFileChooser
ファイルを選択するためのコンポーネント
JFrame
java.awt.Frame を拡張する外部フレーム
JInternalFrame
JDesktopPane に含まれる内部フレーム
JLabel
テキストとグラフィックスを表示するラベル( AWT のラベルを置き換える)
JLayeredPane
異なる階層のコンポーネントを表示できるコンテナ
JList
項目のリストを表示するコンポーネント( AWT のリストを置き換える)
JMenu
メニューバーに表示されるメニュー( AWT のメニューを置き換える)
JMenuBar
メニューを表示するためのメニューバー( AWT のメニューバーを置き換える)
JMenuItem
メニュー項目( AWT のメニュー項目を置き換える)
JOptionPane
メッセージや質問のダイアログなどの標準ダイアログを表示するコンポーネント
JPanel
AWT のパネルとキャンバスのコンポーネントを置き換える包括的なクラス
JPasswordField
入力文字を解読不能にする JTextField の拡張クラス
JPopupMenu
ポップアップメニュー( AWT のポップアップメニューを置き換える)
JProgressBar
進捗状況を表示するコンポーネント
JRadioButton
ラジオボタン( AWT のチェックボックスを置き換える)
JRootPane
ガラスペイン、階層化ペイン、コンテンツペイン、オプションのメニューバーを含む
最上位コンテナ
JScrollBar
スクロールバー( AWT のスクロールバーを置き換える)
JScrollPane
スクロールペイン( AWT のスクロールペインを置き換える)
JSeparator
水平方向と垂直方向のセパレータ
JSlider
スライダー
JSplitPane
水平方向および垂直方向に並べられ、動的にサイズ変更が可能な 2 つの領域を含むコ
ンテナ
JTabbedPane
タブペイン
JTable
テーブル
JTableHeader
テーブルのヘッダー
JTextArea
複数行のテキストを入力するテキスト領域( AWT のテキスト領域を置き換える)
1.4 ユーザーインターフェイスコンポーネント
37
コンポーネントクラス
説明
JTextComponent
テキストコンポーネントの基本クラス( AWT の TextComponent を置き換える)
JTextField
単一行のテキストフィールド( AWT のテキストフィールドを置き換える)
JTextPane
単純なテキストエディタ
JToggleButton
2 つの状態を表すトグルボタン( JCheckBox と JRadioButton の基本クラス)
JToolBar
ツールバー
JToolTip
カーソルがコンポーネント上にあるときに表示される 1 行のツールチップ
JTree
階層構造のデータの表示を制御するコンポーネント
JViewport
スクロール可能なコンポーネントを表示するビューポート
JWindow
java.awt.Window を拡張する外部ウィンドウ
1.4.1 プラグイン可能なルックアンドフィール
Swing は MVC( Model View Controller )アーキテクチャに基づくプラグイン可能なルック
アンドフィールの概念をサポートする。図 1-3 にさまざまなルックアンドフィールで実行した
アプレットの例を示す。
図 1-3 プラグイン可能なルックアンドフィール―(左上から時計回りに)Windows 、Metal( Java )、Motif 、Macintosh
のルックアンドフィール
アプレットまたはアプリケーションのルックアンドフィールを変更する場合、コードを修正
する必要はない。デフォルトのルックアンドフィールは、実行時に$JDK_HOME/lib ディレクト
リの swing.properties ファイルで swing.defaultlaf というプロパティに任意のルックアン
ドフィールを設定することによって指定できる。次に、defaultlaf プロパティによってデフォ
ルトのルックアンドフィールを設定する swing.properties ファイルの例を示す。
38
Chapter 1 概要
# swing.properties ファイルの例
# ‘ # ’で始まる行はコメントを示す
# この例では Windows のルックアンドフィールがデフォルトとして指定されている
# ルックアンドフィールが指定されない場合、Java のデフォルトのルックアンドフィール( Metal )が使われる
# 次の行はインストールされているルックアンドフィールを示す
swing.installedlafts=metal,motif,windows,mac
# デフォルトを Windows のルックアンドフィールに設定する
swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel
# swing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel
# swing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel
Swing のプラグイン可能なルックアンドフィールの実装については、Chapter 7「プラグイン
可能なルックアンドフィール」で解説する。
1.5 Swing パッケージの概要
Swing は、表 1-2 に示すパッケージから構成される。
表 1-2 Swing のパッケージ
パッケージ
説明
com.sun.java.swing.plaf.motif
Motif のルックアンドフィールを実装する UI の委譲先クラス
com.sun.java.swing.plaf.windows Windows のルックアンドフィールを実装する UI の委譲先クラス
javax.swing
Swing のコンポーネントとユーティリティ
javax.swing.border
Swing の軽量コンポーネントのボーダー
javax.swing.colorchooser
JColorChooser をサポートするクラスまたはインターフェイス
javax.swing.event
イベントおよびリスナーのクラス
javax.swing.filechooser
JFileChooser をサポートするクラスまたはインターフェイス
javax.swing.plaf
UI の委譲先の動作を規定する抽象クラス
javax.swing.plaf.basic
すべての標準ルックアンドフィールの共通機能を実装する基本クラス
javax.swing.plaf.metal
Metal のルックアンドフィールを実装する UI の委譲先クラス
javax.swing.plaf.multi
多重ルックアンドフィールをサポートするクラス
javax.swing.table
JTable コンポーネントのサポートクラス
javax.swing.text
テキストの表示と編集をサポートするクラス
javax.swing.text.html
HTML ファイルの表示と編集をサポートするクラス
javax.swing.text.html.parser
HTML ファイルの解析クラス
javax.swing.text.rtf
RTF ファイルの表示と編集をサポートするクラス
javax.swing.tree
JTree コンポーネントのサポートクラス
javax.swing.undo
元に戻す機能をサポートするクラス
javax.swing は Swing が提供する最大のパッケージで、約 90 のクラスと 23 のインターフェ
イスを持つ。Swing コンポーネントのほとんどが javax.swing に含まれる。JTableHeader と
JTextComponent は例外で、それぞれ javax.swing.table パッケージと javax.swing.text
パッケージに含まれる。
1.5 Swing パッケージの概要
39
javax.swing.border は Swing の軽量コンポーネントの周囲にボーダーを描画するクラスを
含む。このパッケージは、Border インターフェイス、AbstractBorder クラス、AbstractBorder
を拡張する数多くの具象クラスから構成される。
イベントとイベントリスナーは、java.awt.event に似た javax.swing.event パッケージ
に含まれる。java.awt.event と javax.swing.event はイベントクラスとリスナーインター
フェイスを含み、AWT と Swing のコンポーネントから発行されるイベントの処理に使われる。
たとえば、Swing の TreeExpansionListener インターフェイスは、ツリーコンポーネントで
ノードの展開(または収縮)のイベント処理が必要な場合に実装する。TreeExpansionListener
インターフェイスで定義されるメソッドは TreeExpansionEvent のインスタンスを受け取る。
TreeExpansionListener と TreeExpansionEvent はどちらも javax.swing.event パッケー
ジの中で定義されている。
Swing のテーブルコンポーネント( JTable )は javax.swing に含まれるが、そのサポートク
ラスは javax.swing.table にある。テーブルのモデル、セルレンダラ、エディタなどはすべ
て javax.swing.table に含まれる。
JTable クラスと同様に、Swing のツリークラス(階層構造のデータのフレームワークとなる
JTree コンポーネント)は javax.swing に含まれるが、サポートクラスは javax.swing.tree
にある。javax.swing.tree はツリーのモデル、ノード、ツリーのエディタやレンダラなどの
サポートクラスを含む。
Swing には文書の表示と編集を行うために、javax.swing.text 、javax.swing.text.html 、
javax.swing.text.html.parser 、javax.swing.text.rtf が含まれる。javax.swing.text
は 、Swing のドキュメントモデルの基本構造に必要なすべてのクラスを含み 、ドキュメン
ト、要素、キャレット、ハイライタ、エディタなどのクラスとインターフェイスを提供する。
javax.swing.text.html と javax.swing.text.rtf は Swing で最も小さいパッケージで、そ
れぞれ HTML
( Hypertext Markup Language )と RTF
( Rich Text Format )のドキュメントの
エディタを実装するための機能を提供する。javax.swing.text.html.parser は HTML ファ
イルを解析するサポートクラスを含む。
javax.swing.undo は、元に戻す機能の実装に必要なサポートクラスを提供する。
javax.swing.plaf は、Swing のプラグイン可能なルックアンドフィールにおいて UI の委
譲先の基本機能を提供する。UI の委譲先は対応するルックアンドフィールを実装する。
javax.swing.plaf のクラスは UI のリソースを設定する、javax.swing.plaf.ComponentUI
クラスを拡張するなどにより UI の委譲先に共通する動作を設定する。一般に javax.swing.plaf
パッケージの UI の委譲先クラス( クラス名の最後が UI であるクラス)は特定のコンポーネン
トに対して追加の抽象メソッドを定義する。たとえば、javax.swing.plaf.ButtonUI クラス
は javax.swing.plaf.ComponentUI クラスを拡張し、ボタンの内部と境界とのマージンを返
す抽象メソッド( getDefaultMargin() )を追加する。
javax.swing.plaf.basic は javax.swing.plaf で定義されるクラスを拡張し、Swing の標
準ルックアンドフィールに共通する機能を実装している。たとえば、javax.swing.plaf.basic.
BasicButtonUI クラスは javax.swing.plaf の ComponentUI クラスと ButtonUI クラスによ
40
Chapter 1 概要
って定義されるメソッドのデフォルトの実装を提供する。BasicButtonUI クラスは、ボタンの
テキストとアイコンを描画する paint() などのメソッドの他に、paintButtonPressed() のよ
うにルックアンドフィール固有のメソッドを実装する。ルックアンドフィール固有のメソッド
は処理を行わないメソッドとして実装され、ルックアンドフィール固有の拡張クラスによって
オーバーライドされる。
javax.swing.plaf.metal と javax.swing.plaf.motif は、それぞれのルックアンドフィー
ルに対応する UI の委譲先クラスを実装する。UI の委譲先クラスは javax.swing.plaf.basic
のクラスを拡張し、ルックアンドフィール固有の動作を実装する。たとえば、javax.swing.plaf.
metal.MetalButtonUI クラスは、javax.swing.plaf.basic.BasicButtonUI では処理を行わ
ない paintButtonPressed() をオーバーライドする。
javax.swing.plaf.multi はルックアンドフィールの多重化をサポートする。ルックアンド
フィールの多重化では、1 つのコンポーネントに複数の UI の委譲先クラスを関連付ける。たと
えば、ボタンの UI の委譲先を画像と音声の委譲先に関連付けることにより、ボタンが押され
たときに通常の画像の処理と共に音を出すことができる。ルックアンドフィールの多重化は主
にアクセスのサポートを目的としたコンポーネントの機能の拡張に便利である。
Swing はこの他に Macintosh のルックアンドフィールの実装を提供している。
1.6 SwingとAWT
Swing は AWT を置き換えるように設計されていると誤解されることが多いが、実際には図
1-4 に示すように AWT 上に構築されている。
Swingの重量コンポーネント
Swingの軽量コンポーネント
AWT
フレーム、ウィンドウ、ダイアログ
コンポーネント、コンテナ、グラフィックス、色、フォント、
ツールキット、レイアウトマネージャなど
図 1-4 Swing と AWT の関係
Swing は、グラフィックス、色、フォント、ツールキット、レイアウトマネージャなどの AWT の
基本構造を利用するが、AWT コンポーネントは使わない。Swing と関連を持つ AWT コンポー
ネントは Frame 、Window 、Dialog だけで、Swing の重量コンポーネントの JFrame 、JWindow 、
JDialog はそれぞれを拡張する。つまり、Swing は AWT の優れた部分を使って新しい軽量コ
ンポーネントを構築し、AWT の問題点である重量コンポーネントをそのまま残している。
1.7 Swing の実行
41
Swing は AWT の重量コンポーネントを置き換えるが、AWT そのものは置き換えない。
Swing に精通するためには、AWT の基本構造を理解する必要がある。
Swing はグラフィックス、フォント、レイアウトマネージャなどの AWT の機能を利用す
るが、Swing の軽量コンポーネントはすべて究極的には AWT の Container クラスを継承す
る。AWT の Container クラスは、AWT の Component を拡張する。言い換えると、Swing は
AWT の基本構造を利用することに加え、すべての Swing コンポーネントは実際には AWT の
コンテナになる。AWT の Container クラスそのものは軽量コンポーネントであり( つまりピ
アを持たない*3 )、コンテナのウィンドウでレンダリングされることに注意しよう。
1.6.1 ピアとプラグイン可能なルックアンドフィール
Swing と AWT のコンポーネントは共に他のオブジェクトに委譲を行い、コンポーネントの
表示やイベントの処理に関連する多くの作業を実行する。AWT コンポーネントの委譲先はネ
イティブなピアであるが、Swing コンポーネントの委譲先は ComponentUI クラスの拡張であ
る。Swing と AWT のコンポーネントはどちらも委譲を行うが、委譲の効果は著しく異なる。
AWT コンポーネントはネイティブなピアに委譲するため、動作の拡張が難しい場合もある。
たとえば、AWT のボタンに画像を追加することはできない。これは、おそらく C++で作成さ
れたネイティブなピアでボタンのレンダリングが行われるために、この処理を拡張できないか
らだ。同様に、テキストのハイライトはテキスト領域のピアが行うため、テキスト領域がテキ
ストのハイライトの方法を変更することはできない。つまり、ネイティブなピアにより実装さ
れた動作は変更や拡張が不可能である。
一方、Swing コンポーネントの委譲先( ComponentUI )は Swing のツールキットに含まれる
Java クラスであり、コンポーネントの動作を変更するように拡張できる。Swing のプラグイ
ン可能なルックアンドフィールの設計は修正した MVC アーキテクチャに基づいており、コン
ポーネントの UI の委譲先はコンポーネントのレンダリングとイベント処理を行うビューとコ
ントローラである。Swing のコンポーネントが変更されたユーザーインターフェイスを備えて
いる場合、コンポーネントの外観とイベント処理は変更可能である。
1.7 Swingの実行
Swing は JDK 1.1 または 1.2 以降で使用可能である。Swing は JDK 1.2 には含まれているが、
JDK 1.1 には含まれていない。Swing を JDK 1.1 で使う場合、次に示す Web サイトからダウ
ンロードする。
●
http://java.sun.com/products/jfc/index.html
*3 java.awt.Container は、単なるプレースホルダとして処理を行わないピアを持つ。
42
Chapter 1 概要
1.7.1 Web ブラウザにおけるSwingの使用
Swing のアプレットは Netscape Navigator や Internet Explorer で動作するが、JDK 1.1 を
サポートする場合に限られる。
■ Netscape Navigator
Netscape Navigator については 4.04 以降のバージョンが必要であり、JDK 1.1 のパッチ*4 を
当てる必要がある。Netscape Navigator と JDK 1.1 のパッチは、次の Web サイトからダウン
ロードする。
●
http://developer.netscape.com/software/jdk/download.html
図 1-5 に、Netscape Navigator で簡単な Swing アプレットを実行した例を示す。
図 1-5 Netscape Navigator における Swing アプレットの実行例
適切なバージョンの Netscape Navigator と JDK 1.1 のパッチをインストールした後に、Swing
*5
の jar ファイルをブラウザから利用可能な状態に設定する。
この場合、Swing の jar ファイ
ルを Netscape のディレクトリにコピーする方法と、システムの CLASSPATH を修正する方法
がある。ここでは最初の方法について説明する。CLASSPATH の修正は Internet Explorer と
Netscape Navigator に共通するため、「 Internet Explorer 」で説明する。
Swing の jar ファイルを Netscape の javaYclasses ディレクトリにコピーする。たとえば、
Netscape が C:Y ドライブに、Swing が C:Yswing ディレクトリにインストールされている場合、
Swing のすべての jar ファイルを C:Yswing から C:YProgram FilesYNetscapeYCommunicator
YProgramYjavaYclasses にコピーする。Netscape Navigator と JDK 1.1 をインストールし、
Swing の jar ファイルを Netscape から利用可能にすれば、Netscape Navigator で Swing ア
プレットを実行することができる。
*4 訳注: Netscape Navigator 4.06 以降では JDK 1.1 のパッチは不要である。
*5 訳注: これも Netscape Navigator 4.06 以降では不要である。
1.7 Swing の実行
43
■ Internet Explorer
Internet Explorer 4.0 以降は JDK 1.1 をサポートする。適切なバージョンの Internet
Explorer をインストールして、Swing の jar ファイルを Internet Explorer から利用可能にす
ると、Swing アプレットを Internet Explorer で実行できる。続いて、システムの CLASSPATH
の設定方法を説明する。
●
Windows NT [ コントロールパネル]の[ システム]をダブルクリックし、[ システムの
プロパティ]で[ 環境]タブをクリックする。図 1-6 に示すように、[ ユーザー環境変数]
というリストに CLASSPATH 変数を追加する。
CLASSPATH には、JDK の classes.zip ファイルと swingall.jar ファイルを設定する必
要がある。たとえば、図 1-6 では、JDK と Swing がどちらも D:Y ドライブにインストー
ルされている場合の CLASSPATH 変数の設定例を示している。CLASSPATH を追加または修
正したら、[ OK ]ボタンをクリックして[システムのプロパティ]ウィンドウを閉じる。こ
れにより、Swing アプレットが Internet Explorer で実行可能になる。
図 1-6 Windows NT における CLASSPATH の構成
●
Windows 95 または Windows 98 C:Y ドライブの Autoexec.bat ファイルを編集し、次
のエントリを追加する。
SET CLASSPATH=D:YjdkYlibYclasses.zip;D:YswingYswingall.jar
この場合、CLASSPATH 変数を追加または修正した後にシステムを再起動する必要がある。
図 1-7 に、Internet Explorer で簡単な Swing アプレットを実行した例を示す。
44
Chapter 1 概要
図 1-7 Internet Explorer における Swing アプレットの実行例
■ Java プラグイン
Netscape Navigator または Internet Explorer を設定し、Swing アプレットの実行を試み
ると、間違いなくさまざまなバグが見つかる。この問題は Swing に起因するのではなく、イン
ターネットで利用する Java アプレットを開発する際の問題によるものと考えられる。
アプレットの開発における難問の 1 つは、アプレットをすべてのブラウザで同じように動作
させることだ。また、これまでの経緯を見ると、ブラウザのベンダーが JDK の最新バージョン
に対応するようにブラウザを更新するまでには時間がかかる。幸い、Sun Microsystems は、
この問題のすばらしい解決策として Java プラグイン( 旧 Activator )を提供している。
Java プラグインは、Netscape Navigator にプラグインを挿入したり、Internet Explorer で
ActiveX コントロールを実行することにより動作する。このプラグインと ActiveX コントロー
ルはブラウザに Sun Microsystems の JDK の最新バージョンを効果的に導入する。Java プラ
グインを使うと、アプレットが異なるブラウザでも同じように動作することが保証される。
Java プラグインの唯一の問題点は HTML ファイルを変更しなければならないことだが、Sun
Microsystems は必要な変更を行うツールを提供している。Java プラグインは無償で提供されて
( http://java.sun.com/products/jdk/1.2/ja/features.
いる。詳細については Web サイト
html )を参照してほしい。
1.8 Swingに関する情報
Swing を学ぶ場合、本書の他にもさまざまな情報を入手可能である。特に、本書で解説して
いない特定の質問については、このような情報源を利用するとよい。
最適な情報の 1 つとして、まず Swing に付属するサンプルコードが挙げられる。コード
例として数多くの小さく完全なアプレットやアプリケーションが提供されており、Swing の
広範な機能を利用している。Swing のコード例は JDK をインストールしたディレクトリの
demoYjfc ディレクトリに格納されている。たとえば、JDK を C:YJDK1.2 にインストールした
1.9 まとめ
45
場合、C:YJDK1.2YdemoYjfc の任意のディレクトリに Swing のコード例を見つけることがで
きる。
また、インターネット上にはメーリングリストやニュースグループなど、数多くの情報源が
ある。次に示すニュースグループで Swing に関する質問を投稿するとよい。
●
comp.lang.java.programmer
●
comp.lang.java.gui
また、経験年数に関係なく利用できるメーリングリストがある。メーリングリストの詳細に
ついては、Web サイト( http://www.eos.dk/ )を参照してほしい。
Sun Microsystems が運営する Swing のオフィシャルサイトとして Swing Connection があ
る。Swing Connection の Web サイトを次に示す。
●
http://java.sun.com./products/jfc/tsc/
1.9 まとめ
Java は 1995 年に登場してまもなく急速に広まり、その成功は Java 言語の開発者さえも驚く
ほどであった。Java の前身は、C++を簡易化して使いやすくした Sun Microsystems の研究
用言語の Oak であるが、インターネットで利用されるようになり名前を Java に変えた。
Java は開発に数年間を要し、Sun Microsystems の社内用の言語であったため、ユーザーイ
ンターフェイスツールキットについてはほとんど考慮されていなかった。Java の成功が明らか
になってくると、Java はユーザーインターフェイスツールキットを持たざるを得なくなり、し
かも短期間に開発しなければならなかった。ユーザーインターフェイスツールキットを最も速
く開発するために、ほとんどの処理をピアと呼ばれるネイティブなコンポーネントに依存し、
ネイティブなコンポーネントを Java クラスで薄くラップする方法が採用された。このように
AWT は小人数の開発チームでわずか 6 週間で開発されたのである。
ピアのアーキテクチャは大規模なアプリケーションの構築には適さないうえ、異なるプラッ
トフォーム間で互換性を持たない。また、AWT は正確にはオブジェクト指向ではない。たとえ
ば、最初のイベントモデルではイベントの種類に応じて異なるコードを呼び出すために switch
文を使う必要があった。このような switch 文は、オブジェクトの種類を多相性により処理す
*6
べきであると主張するオブジェクト指向の概念に違反するものである。
AWT の最初のバージョンにおける短所は、Java の開発者、Sun Microsystems やその競争
相手によって問題視された。そのため、すぐに AWT に置き換わるツールキットが次々と登場
する。まもなく、Sun Microsystems は新しいイベントモデルとピアを持たない軽量コンポーネ
ントを含む AWT 1.1 をリリースしたが、AWT 1.1 における改良は Java の開発者が他のユー
ザーインターフェイスツールキットに移行するのを止めるほど十分なものではなかった。
*6 オブジェクト指向設計で switch 文が有効な場合もあるが、AWT のイベントモデルはこれに該当しない。
46
Chapter 1 概要
JavaSoft は、Java のコミュニティが複数のユーザーインターフェイスツールキットにより分
断されようとしていることを認識し、Netscape と共同で Swing コンポーネントの構築を計画
した。Swing は Netscape と Sun Microsystems の技術者により約 1 年半をかけて開発され、
AWT に比べて格段に改善された。
Swing コンポーネントの一部は AWT の重量コンポーネントを置き換えるが、Swing そのも
のは AWT を置き換えるわけではない。Swing は AWT の拡張であり、グラフィックス、フォ
ント、レイアウト管理を含む AWT の基本構造の多くを利用する。Swing を使いこなすために
*7
は AWT の基本構造を根本から理解する必要がある。
Swing は、他のすべてのソフトウェアと同様に完全ではない。現在、Swing にはバグがあり、
場所によっては設計上の短所も見られるが、最初の AWT に比べると大幅に改善されており、
信頼性の高いユーザーインターフェイスツールキットになっている。
*7 『グラフィック Java2 Vol.1 AWT 編』を参照。