目 次 はじめに 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 編』を参照。
© Copyright 2024 Paperzz