目 次
Part 2
●Swing
コンポーネント
Chapter 14
ウィンドウとダイアログ
18
14.1 JWindow
クラス 20 14.1.1 JWindowのプロパティ 25 14.1.2 JWindowの概要 25 14.1.3 AWTとの互換性 2714.2 JDialog
クラス 28 14.2.1 JDialogのプロパティ 32 14.2.2 JDialogの概要 33 14.2.3 AWTとの互換性 3614.3 JOptionPane
クラス 36 14.3.1 内部フレーム 39 14.3.2 JOptionPaneのスタティックメソッド 41 14.3.3 メッセージダイアログ 43 14.3.4 確認ダイアログ 49 14.3.5 入力ダイアログ 52目 次 6 14.3.6 オプションダイアログ 58 14.3.7 JOptionPaneのプロパティ 62 14.3.8 JOptionPaneのイベント 65 14.3.9 JOptionPaneの概要 68 14.3.10 AWTとの互換性 78
14.4
まとめ 78Chapter 15
内部フレームとデスクトップペイン
80
15.1 JInternalFrame
クラス 81 15.1.1 JInternalFrameのプロパティ 85 15.1.2 JInternalFrameのイベント 87 15.1.3 JInternalFrameの概要 94 15.1.4 AWTとの互換性 10015.2 JDesktopPane
クラス 100 15.2.1 JDesktopPaneのプロパティ 107 15.2.2 JDesktopPaneのイベント 107 15.2.3 JDesktopPaneの概要 107 15.2.4 AWTとの互換性 10915.3 DesktopManager
インターフェイス 109 15.3.1 DefaultDesktopManagerの概要 11715.4
まとめ 118Chapter 16
チューザ
120
16.1 JFileChooser
クラス 121 16.1.1 ファイルチューザの種類 126 16.1.2 アクセサリコンポーネント 130 16.1.3 ファイルの種類によるフィルタ 134 16.1.4 ファイルビュー 144 16.1.5 複数選択 149 16.1.6 JFileChooserのプロパティ 152 16.1.7 JFileChooserのイベント 156 16.1.8 JFileChooserの概要 161 16.1.9 AWTとの互換性 168目 次 7
16.2 JColorChooser
クラス 168 16.2.1 カラーチューザの表示 170 16.2.2 カラーチューザのカスタマイズ 175 16.2.3 JColorChooserのプロパティ 185 16.2.4 JColorChooserのイベント 186 16.2.5 JColorChooserの概要 187 16.2.6 AWTとの互換性 18916.3
まとめ 189Chapter 17
リスト
190
17.1
リストのモデル 193 17.1.1 AbstractListModelクラス 195 17.1.2 DefaultListModelクラス 19617.2
リストの選択 20217.3
リストのセルレンダラ 20417.4 JList
クラス 211 17.4.1 JListのプロパティ 212 17.4.2 JListのイベント 216 17.4.3 JListの概要 233 17.4.4 AWTとの互換性 23817.5
まとめ 238Chapter 18
コンボボックス
240
18.1
コンボボックスとリスト 24118.2
コンボボックス 24218.3
コンボボックスのモデル 243 18.3.1 ComboBoxModelインターフェイス 245 18.3.2 MutableComboBoxModelインターフェイス 245 18.3.3 DefaultComboBoxModelクラス 24618.4
コンボボックスのセルレンダラ 24718.5
コンボボックスのキー選択マネージャ 251 18.5.1 デフォルトのキー選択マネージャ 252 18.5.2 カスタムのキー選択マネージャ 255 18.5.3 プログラムによるキー選択 259目 次 8
18.6
コンボボックスのエディタ 26318.7 JComboBox
クラス 274 18.7.1 JComboBoxのプロパティ 275 18.7.2 JComboBoxのイベント 276 18.7.3 JComboBoxの概要 280 18.7.4 AWTとの互換性 28518.8
まとめ 286Chapter 19
テーブル
288
19.1
テーブルとスクロール 290 19.1.1 ブロック増分値とユニット増分値 29219.2
テーブルのモデル 293 19.2.1 テーブルのデータモデル 294 19.2.2 TableModelインターフェイス 295 19.2.3 AbstractTableModelクラス 297 19.2.4 DefaultTableModelクラス 300 19.2.5 テーブルのモデルおよびデフォルトのレンダラとエディタ 30619.3
テーブルの列 310 19.3.1 列のサイズ変更 311 19.3.2 列の幅 31519.4
テーブルの列のモデル 323 19.4.1 DefaultTableColumnModelクラス 324 19.4.2 列マージン 325 19.4.3 列の追加と削除 329 19.4.4 左端の列の固定 33119.5
テーブルの選択 33719.6
レンダリングと編集 341 19.6.1 テーブルのセルのレンダラとエディタ 341 19.6.2 TableCellRendererインターフェイス 347 19.6.3 CellEditorインターフェイス 353 19.6.4 TableCellEditorインターフェイス 355 19.6.5 TableCellEditorの実装 35719.7
テーブルの行 368 19.7.1 行の高さ 368 19.7.2 行のレンダリング 371目 次 9
19.8
テーブルのデコレータ 373 19.8.1 デコレータのソート 37719.9
テーブルのヘッダー 382 19.9.1 JTableHeaderクラス 383 19.9.2 列ヘッダーのレンダラとツールチップ 38419.10 JTable
クラス 389 19.10.1 JTableのプロパティ 390 19.10.2 JTableのイベント 393 19.10.3 TableModelEventクラス 393 19.10.4 TableColumnModelEventクラス 397 19.10.5 ListSelectionEventクラス 399 19.10.6 JTableの概要 401 19.10.7 AWTとの互換性 40819.11
まとめ 408Chapter 20
ツリー
410
20.1
ツリーの生成 41220.2
ツリーのノード 416 20.2.1 TreeNodeインターフェイス 416 20.2.2 MutableTreeNodeインターフェイス 417 20.2.3 DefaultMutableTreeNodeクラス 41720.3
ツリーのパス 42620.4
ツリーのモデル 430 20.4.1 DefaultTreeModelクラス 43120.5
ツリーの選択 439 20.5.1 DefaultTreeSelectionModelクラス 44220.6
ツリーのノードのレンダリング 446 20.6.1 DefaultTreeCellRendererクラス 446 20.6.2 Metalのルックアンドフィール 457 20.6.3 ルートのノードとハンドル 45720.7
ツリーのノードの編集 459 20.7.1 DefaultCellEditorの拡張 460 20.7.2 DefaultTreeCellEditorクラス 461目 次 10
20.8
レンダリングと編集の例 466 20.8.1 Testクラス 468 20.8.2 SelectableFileクラスとFileNodeクラス 470 20.8.3 レンダラ 471 20.8.4 エディタ 47320.9 JTree
クラス 476 20.9.1 JTreeのプロパティ 477 20.9.2 JTreeのイベント 479 20.9.3 JTreeの概要 493 20.9.4 AWTとの互換性 50020.10
まとめ 500Chapter 21
テキストの概要
502
21.1 Swing
のテキストコンポーネント 503 21.1.1 javax.swing.textパッケージ 50521.2
アクション 506 21.2.1 テキストのアクション 506 21.2.2 アクションとエディタキット 51021.3
キーマップ 51421.4
ドキュメント 518 21.4.1 ドキュメントのカスタマイズ 521 21.4.2 ドキュメントのリスナー 52321.5
キャレットとハイライタ 527 21.5.1 キャレット 527 21.5.2 キャレットのリスナー 529 21.5.3 キャレットのカスタマイズ 531 21.5.4 ハイライタ 53321.6
元に戻す/
やり直し 53521.7 JTextComponent
クラス 539 21.7.1 JTextComponentのプロパティ 541 21.7.2 JTextComponentの概要 54321.8
まとめ 548目 次 11
Chapter 22
テキストコンポーネント
550
22.1 JTextField
クラス 551 22.1.1 水平方向の表示範囲とスクロールオフセット 555 22.1.2 テキストフィールドのレイアウト 558 22.1.3 テキストフィールドの検証 562 22.1.4 JTextFieldのプロパティ 566 22.1.5 JTextFieldのイベント 567 22.1.6 JTextFieldの概要 570 22.1.7 AWTとの互換性 57322.2 JPasswordField
クラス 574 22.2.1 JPasswordFieldのプロパティ 576 22.2.2 JPasswordFieldの概要 57622.3 JTextArea
クラス 578 22.3.1 JTextAreaのプロパティ 582 22.3.2 JTextAreaの概要 582 22.3.3 AWTとの互換性 58522.4 JEditorPane
クラス 586 22.4.1 JEditorPaneのプロパティ 589 22.4.2 JEditorPaneのイベント 589 22.4.3 JEditorPaneの概要 59222.5 JTextPane
クラス 595 22.5.1 アイコンとコンポーネントの埋め込み 595 22.5.2 コンテンツに対する属性の適用 597 22.5.3 JTextPaneのプロパティ 605 22.5.4 JTextPaneの概要 605 22.5.5 AWTとの互換性 60822.6
まとめ 608Chapter 23
テキストコンポーネントのカスタマイズ
610
23.1
概要 61123.2 AttributeSet
とStyleConstants
61423.3
アクションのカスタマイズ 617目 次 12
23.4
ビュー 621 23.4.1 ビューのカスタマイズ 62223.5
書式とStyleContext
クラス 62623.6
要素 63323.7
まとめ 636Appendix A
クラスダイアグラム
637
Appendix B
ルックアンドフィールの定数
641
索 引 655C
HAPTER
14
JWindowクラス -JWindowのプロパティ -JWindowの概要 JDialogクラス -JDialogのプロパティ -JDialogの概要 JOptionPaneクラス -内部フレーム -JOptionPaneのスタティックメソッド -メッセージダイアログ -確認ダイアログ -入力ダイアログ -オプションダイアログ まとめウィンドウと
ダイアログ
Swingのウィンドウ、フレーム、ダイアログは、それぞれAWTのWindowクラス、Frame
クラス、Dialogクラスを拡張する重量コンポーネントである。この3つのコンポーネントはす べてウィンドウであり、相違点が明白にはわかりにくいため、状況に応じて使用するコンポー ネントの選択に迷う場合がある。コンポーネントの違いを明確にするために、AWTの各コン ポーネントのプロパティを表14-1にまとめる。 表14-1 ウィンドウ、フレーム、ダイアログのプロパティ プロパティ ウィンドウ フレーム ダイアログ モーダル No No No/CSG サイズの変更可能 No Yes/SG Yes/SG メニューバー No Yes/SG No
フォーカスマネージャ Yes Yes Yes
警告文字列 Yes/G Yes/G Yes/G
タイトル No Yes/CSG Yes/CSG
ボーダー No Yes Yes
タイトルバー No Yes Yes
アイコン画像∗ No Yes/SG No
Frameから起動される Yes No Yes
文中のYes、Noはデフォルトの状態を意味する。
Cは構築時に設定可能、Sは設定用のメソッドが使用可能、Gは取得用のメソッドが使用可能であることを示す。
Chapter 14 ウィンドウとダイアログ 20 ウィンドウは3つのうちで最も基本的なコンポーネントであり、FrameとDialogのスーパー クラスになる。ウィンドウはボーダー、タイトルバー、メニューバーを持たず、サイズを変更 できない。ウィンドウは、他のコンポーネント上に表示され、ボーダーを持たない矩形の領域 に、オブジェクトを表示する場合に適している。 フレームはWindowの拡張クラスで、ボーダーとタイトルバーを含み、サイズを変更できる。 フレームは、アプリケーションウィンドウをアイコン化したり、メニューバーが必要な場合に 適している。 ダイアログもまたWindowの拡張クラスで、フレームと同様にボーダーとタイトルバーを含 み、サイズの変更が可能である。フレームとウィンドウはモーダルには設定できないが、ダイ アログはモーダルに設定できる。ダイアログは、ユーザーに入力を促すために一時的にウィン ドウを表示するときなどに適している。 Swingのウィンドウ、フレーム、ダイアログは、対応するAWTのクラスにルートペインを 追加する。Swingのウィンドウ、フレーム、ダイアログにコンポーネントを追加する場合、そ れぞれのルートペインに含まれるコンテンツペインにコンポーネントを追加する。また、レイ アウトマネージャは、コンテナそのものではなく、コンテンツペインに設定する。 JRootPaneクラスによって表されるルートペインとJFrameクラスによって表されるフレー ムは、本章では説明しない。ルートペインとフレームは、Chapter 2「Swingの基礎」で解説 している。AWTのFrameクラス、Windowクラス、Dialogクラスについては『グラフィック
Java2 Vol.1 AWT編』を参照してほしい。
14.1 JWindow
クラス
JWindowはSwingの重量コンポーネントで、java.awt.Windowを拡張する。ウィンドウは 唯一のコンポーネントとしてJRootPaneのインスタンスを含む。JWindowのインスタンスは ボーダー、タイトルバー、メニューバーなどを持たず、サイズを変更する機能を提供していな い。Swingのウィンドウは、一般に他のコンポーネントの最前面に表示され、ボーダーを持た ない領域に、コンポーネントやグラフィックスを表示するために利用される。たとえば、Swing のツールチップはJWindowのインスタンスを使って実装される。 図14-1に、JWindowクラスの用途の1つであるスプラッシュスクリーンの例を示す。アプ リケーションはウィンドウを生成し、そこに画像アイコンを持つJLabelのインスタンスを追 加する。ウィンドウは、マウスのダブルクリックが検出されるとクリアされる。 リスト14-1に、図14-1のアプレットのコードを示す。 このアプリケーションはJWindowの引数なしのコンストラクタを使ってインスタンスを生成 し、画像アイコンを指定してJLabelのインスタンスを生成する。ラベルにはボーダーファク トリから取得した浮き彫りの斜影ボーダーを設定し、ラベルをウィンドウのコンテンツペイン に中央のコンポーネントとして追加する。続いてウィンドウが画面の中央に表示されるように、 AWTのツールキットを使って画像のサイズを取得し、ウィンドウの表示位置を計算する。
14.1 JWindowクラス 21 図14-1 JWindowのインスタンスを使ってスプラッシュスクリーンを実装する リスト14-1 JWindowを使用してスプラッシュスクリーンを実装する import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JFrame {
Toolkit toolkit = Toolkit.getDefaultToolkit();
JWindow window = new JWindow();
JLabel label = new JLabel(new ImageIcon("mandrill.jpg"));
static public void main(String[] args) { JFrame frame = new Test();
} public Test() { label.setBorder(BorderFactory.createRaisedBevelBorder()); window.getContentPane().add(label, "Center"); centerWindow(); window.show(); window.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) {
if(e.getClickCount() == 2) { window.dispose(); System.exit(0); } } }); }
private void centerWindow() {
Dimension scrnSize = toolkit.getScreenSize();
Chapter 14 ウィンドウとダイアログ
22
int labelWidth = labelSize.width, labelHeight = labelSize.height; window.setLocation(scrnSize.width/2 - (labelWidth/2), scrnSize.height/2 - (labelHeight/2)); window.pack(); } } 設定が完了すると、pack()とshow()によりウィンドウが表示される。ウィンドウ、フレー ム、ダイアログに対してpack()を呼び出すと、含まれるコンポーネントに合わせてサイズが 調整される。ウィンドウに追加されたマウスイベントリスナーはウィンドウを破棄し、続いて アプリケーションを終了する。dispose()はウィンドウを隠し、ウィンドウのネイティブシス テムのリソースを破棄する。 JWindowのインスタンスは重量コンポーネントであるため、JComponentクラスの機能はまっ たく継承しないことに注意してほしい。たとえば、JWindowクラスはsetBorder()を実装して いないため、JWindowのインスタンスにボーダーを設定することはできない。 しかし、JWindowのインスタンスは軽量コンポーネントとしてJRootPaneのインスタンスを 含むため、ルートペインに対して他の軽量コンポーネントと同様に処理を実行できる。たとえ ば、図14-2のアプレットでは、JWindowのインスタンスに含まれるルートペインに対して、浮 き彫りの斜影ボーダーを設定する。ルートペインはウィンドウの中央コンポーネントとして指 定されるため、ウィンドウのサイズに合わせて拡張される。したがって、ルートペインにボー ダーを設定することにより、ウィンドウにボーダーを設定できる。また、ウィンドウのルート ペインにはメニューバーが追加されている。 図14-2 アプリケーションウィンドウとしてJWindowのインスタンスを使う
14.1 JWindowクラス 23 図14-2のようなウィンドウには注意が必要である。Swingのウィンドウは、フレームのよ うにアイコン化、最大化、クローズのボタンなどを持たない。アプリケーションウィンドウが 必要な場合には、通常はJFrameのインスタンスを使うほうがよい。図14-2のアプレットは、 単にウィンドウのルートペインの操作方法を示すことを目的としている。 リスト14-2 アプリケーションウィンドウとしてJWindowのインスタンスを使う import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JApplet {
JWindow window = new JWindow();
JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu("File"); JMenuItem quitItem;
public Test() {
final Container contentPane = getContentPane(); JButton button = new JButton("show window ...");
JRootPane windowRootPane = window.getRootPane();
contentPane.setLayout(new FlowLayout()); contentPane.add(button); fileMenu.add("New"); fileMenu.add("Open ..."); fileMenu.add("Save"); fileMenu.add("Save As ..."); fileMenu.addSeparator();
fileMenu.add(quitItem = new JMenuItem("Quit")); menuBar.add(fileMenu);
window.getRootPane().setJMenuBar(menuBar);
window.getRootPane().setBorder(BorderFactory.createRaisedBevelBorder());
button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
Point pt = contentPane.getLocation(); SwingUtilities.convertPointToScreen(pt, contentPane); // コンテンツペインの左上角から10 ピクセル下、10 ピクセル右に表示する window.setBounds(pt.x + 10, pt.y + 10, 200, 200); window.show(); quitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
window.dispose();
} });
Chapter 14 ウィンドウとダイアログ 24 } }); } } このアプレットはJWindowの引数なしのコンストラクタでインスタンスを生成し、ウィンド ウのルートペインの参照を取得する。 また、ウィンドウを表示するために使うボタンを生成する。メニューバーとメニューを生成し て、メニューをメニューバーに追加し、メニューバーをウィンドウのルートペインに追加する。 さらに、ボーダーファクトリからボーダーを取得してウィンドウのルートペインに設定する。 アプレットに含まれるボタンが起動されると、アプレットの左上に幅と高さが200ピクセル のウィンドウが表示される。 JFrameとは異なり、JWindowのインスタンスはクローズボタンを備えていないため、ウィン ドウを破棄するためのリスナーを[Quit]のメニュー項目に追加する。 次に、JWindowクラスについてコンポーネントの概要14-1にまとめる。 コンポーネントの概要14-1 JWindow モデル ― UIの委譲先 ― レンダラ ― エディタ ― 発行されるイベント ― 置き換えられるクラス java.awt.Window クラスダイアグラム 図14-3を参照 java.awt. Window RootPane Container Accessible A JWindow boolean JRootPane extends implements rootPaneCheckingEnabled rootPane implements 図14-3 JWindowのクラスダイアグラム
14.1 JWindowクラス 25
JWindowは重量コンテナであるため、モデル、UIの委譲先、レンダラ、エディタを持たない。
JWindowクラスはjava.awt.Windowを拡張し、AccessibleとRootPaneContainerの各イ ンターフェイスを実装する。JWindowはルートペインの参照と、ルートペインのチェックの有 効または無効を示すboolean値の参照をprotectedとして保持する。ルートペインの詳細に ついては、Chapter 12「軽量コンテナ」の「JRootPaneクラス」を参照してほしい。
14.1.1 JWindowのプロパティ
表14-2に、JWindowクラスのプロパティを示す。 表14-2 JWindowクラスのプロパティ プロパティ名 データ型 種類1 アクセス2 デフォルトcontentPane Container S SG JPanel
glassPane Component S SG Component
layeredPane JLayeredPane S SG JLayeredPane
rootPane JRootPane S SG JRootPane
1 Sは単純なプロパティであることを示す。 2 Sは設定用のメソッドが使用可能、Gは取得用のメソッドが使用可能であることを示す。 ●contentPane JWindowのインスタンスに含まれるコンポーネントを配置するコンテナを 指す。 ●glassPane ルートペインに含まれるすべてのコンポーネントの最前面に表示されるコン ポーネントを指す。 ●layeredPane ルートペインには、ルートペインのメニューバーとコンテンツペインを含 むJLayeredPaneのインスタンスが含まれる。 ●rootPane JWindowのインスタンスが直接含む唯一のコンポーネントである。 ルートペインおよび含まれるコンポーネント( ガラスペイン、階層化ペイン、コンテンツペ イン)については、Chapter 12「軽量コンテナ」で詳しく説明している。
14.1.2 JWindowの概要
次に、JWindowクラスの概要を示す。A P I
JWindow
クラス 拡張 java.awt.Window 実装 RootPaneContainer、javax.accessibility.AccessibleChapter 14 ウィンドウとダイアログ 26 ▼ コンストラクタ public JWindow() public JWindow(Frame) public JWindow(GraphicsConfiguration)*1 public JWindow(Window)
public JWindow(Window, GraphicsConfiguration)
重量ウィンドウは 、所有者であるフレームに付加される。このため 、JWindowクラスは java.awt.Frameの参照を受け取るコンストラクタを提供する。 引数なしのコンストラクタは、ウィンドウを非表示の共有フレームに付加する。この見えな いフレームは、引数なしのコンストラクタが生成するJDialogとJWindowのインスタンスの所 有者になる。共有フレームはSwingUtilities.getSharedOwnerFrame()によって取得する。 ▼ メソッド ●ルートペイン、コンポーネントの追加、レイアウトマネージャの設定に関するメソッド
protected void addImpl(Component, Object, int) protected JRootPane createRootPane()
protected boolean isRootPaneCheckingEnabled() protected void setRootPaneCheckingEnabled(boolean) protected void setRootPane(JRootPane)
public void setLayout(LayoutManager) protected void windowInit()
最初から5番目までのメソッドはウィンドウのルートペインを設定するために使う。JWindow はRootPaneContainerインターフェイスを実装する他のSwingコンポーネントと同様に、ウィ ンドウにコンポーネントを直接追加したり、レイアウトマネージャを直接設定することはでき ない。JWindowにルートペインを追加して、そのルートペインにレイアウトマネージャを設定 する。このために、setRootPaneCheckingEnabled()とisRootPaneCheckingEnabled()を 使って、JWindowのインスタンスにルートペインを追加し、レイアウトマネージャの設定を可 能にすると同時に、外部からこの操作を実行できないように保護している。
createRootPane()はJRootPaneのインスタンスを生成する。このメソッドは、JWindowの 拡張クラスで必要に応じて独自のルートペインを生成できるように、protectedで定義されて いる。 setLayout()は、ウィンドウ以外のオブジェクトによってレイアウトマネージャが設定され たときなど、その処理が実行不可能であることを示す例外を発行する。 *1 編注: Java 2 SDK 1.3では、所有者のWindowや画面などのグラフィックスの設定を受け取るコンストラク タが追加されている。
14.1 JWindowクラス 27 windowInit()はJWindowのコンストラクタによって呼び出される。唯一の役割は、ルート ペインを設定し、ルートペインのチェックを有効化することだ。このメソッドは、JWindowの 拡張クラスがインスタンスの生成時に必要に応じて処理を追加したり、デフォルトの処理を置 き換えることができるように、protectedで定義されている。 ●RootPaneContainerインターフェイスのメソッド
public Container getContentPane() public Component getGlassPane() public JLayeredPane getLayeredPane() public JRootPane getRootPane()
public void setContentPane(Container) public void setGlassPane(Component) public void setLayeredPane(JLayeredPane)
これらのメソッドはRootPaneContainerインターフェイスで定義される。RootPaneContainer
インターフェイスとJRootPaneクラスについては、Chapter 12「軽量コンテナ」を参照してほ しい。
●ユーザー補助機能、その他のメソッド
public AccessibleContext getAccessibleContext() protected String paramString()
public void remove(Component)*2
JWindowはAccessibleインターフェイスを実装しているため、getAccessibleContext()
を実装している。Accessibleインターフェイスについては、Chapter 4「JComponentクラス」 の「ユーザー補助機能」で説明している。また、paramString()はウィンドウを表す文字列を 返す。
14.1.3 AWTとの互換性
JWindowはjava.awt.Windowの拡張クラスであり、AWTのWindowで実装されているパブ リックメソッドをすべて継承する。
SwingとAWTのウィンドウの主な相違点は、Swingのウィンドウがルートペインを含むこ とである。Swingでは、ウィンドウのコンテンツペインに追加することにより、コンポーネン トをウィンドウに追加する。また、レイアウトマネージャもSwingのウィンドウには直接設定 できない。代わりに、コンテンツペインにレイアウトマネージャを設定する。
Chapter 14 ウィンドウとダイアログ
28
14.2 JDialog
クラス
JWindowと同様に、JDialogはSwingの重量コンテナであり、JRootPaneのインスタンス を唯一のコンポーネントとして含む。ただし、ウィンドウとは異なり、Swingのダイアログは ボーダーとタイトルバーを持つ。また、通常はダイアログをクリアするためのクローズボタン をタイトルバーの右側に備えているが、ダイアログのタイトルバーに含まれるコンポーネント はネイティブのウィンドウシステムに依存する。 Swingのダイアログはモーダルに設定できる。つまり、ダイアログが表示されている間はダ イアログの親ウィンドウに対するアクセスを拒否する設定が可能である。モーダルダイアログ を表示するスレッドはダイアログがクリアされるまでブロックされる。ただし、デフォルトで はSwingのダイアログはモーダルではない。 JDialogのインスタンスは、本質的にはJRootPaneのインスタンスを備えたネイティブシス テムのダイアログである。JDialogクラスを使って直接ダイアログを生成する場合、ダイアロ グに含まれるコンポーネントを配置し、ダイアログをクリアするボタンを生成して、ボタンの 起動を監視するリスナーを追加する。Swingはダイアログの生成と表示に関する多くの処理を 自動化するクラスを提供する(「JOptionPaneクラス」を参照)。 図14-4のアプレットはボタンを1つ含み、このボタンをクリックするとダイアログが表示さ れる。図14-4の左側はアプレットの初期状態で、右側はダイアログが表示された様子を示す。 図14-4 JDialogクラスの使用例 このアプレットはConstraintsPanelのインスタンスを生成する。このインスタンスは、 [OK]、[Apply]、[Cancel]の各ボタンを除き、ダイアログ上のコンポーネントをすべて含
14.2 JDialogクラス 29
む。ConstraintsPanelの実装はここで説明する概念には関係がないため、ここではコードを 記載しないが、本書付属のCD-ROMに収録している。
アプレットは[OK]、[Apply]、[Cancel]の各ボタンを含むJPanelのインスタンスを生成 する。また、ダイアログの所有者(Frame)にnullを、タイトルに“Constraints Dialog”を、 モーダルにtrueを指定して、JDialogのインスタンスを生成する。 続いて、ダイアログのgetContentPane()を呼び出してダイアログのコンテンツペインの参 照を取得し、ConstraintsPanelのパネルを中央のコンポーネント、ボタンを含むパネルを下 部のコンポーネントとしてコンテンツペインに追加する。ダイアログに対してpack()が呼び 出されるため、ダイアログのサイズは追加されたコンポーネントに合わせて調整される。 NOTE:pack()にはバグがあり、ダイアログのサイズは推奨値より少し小さくなる。
public class Test extends JApplet {
private ConstraintsPanel cp = new ConstraintsPanel();
private JPanel buttonsPanel = new JPanel();
private JButton showButton = new JButton("show dialog ..."), okButton = new JButton("OK"),
applyButton = new JButton("Apply"), cancelButton = new JButton("Cancel"); private JButton[] buttons = new JButton[] {
okButton, applyButton, cancelButton, };
private JDialog dialog = new JDialog((Frame)null, // 所有者 "Constraints Dialog",// タイトル
true); // モーダル
public Test() {
Container contentPane = getContentPane();
Container dialogContentPane = dialog.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(showButton); dialogContentPane.add(cp, BorderLayout.CENTER); dialogContentPane.add(buttonsPanel, BorderLayout.SOUTH); dialog.pack(); // ...
for(int i=0; i < buttons.length; ++i) { buttonsPanel.add(buttons[i]); } addButtonListeners(); } // ... アプレットのボタンとダイアログのボタンにはリスナーが追加される。アプレットのボタン を起動すると、アプレットに対する相対位置を設定してダイアログを表示する。
Chapter 14 ウィンドウとダイアログ 30 [OK]、[Apply]、[Cancel]の各ボタンにもリスナーが追加される。[OK]ボタン( また は[Cancel]ボタン )を起動すると、dispose()が呼び出され、ダイアログがクリアされる。 dispose()はダイアログを隠し、ダイアログのウィンドウに関連付けられているネイティブシ ステムのリソースを解放する。 // ...
private void addButtonListeners() {
showButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { // setLocationRelativeTo()をここで呼び出すと、 // ダイアログはアプレットの範囲を越えて中央に揃えられる dialog.setLocationRelativeTo(Test.this); dialog.show(); } }); okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { showStatus("OK button Activated");
dialog.dispose(); } }); // ... } リスト14-3に、図14-4のアプレットの完全なコードを示す。 リスト14-3 JDialogクラスの使用例 import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class Test extends JApplet {
private ConstraintsPanel cp = new ConstraintsPanel(); private JPanel buttonsPanel = new JPanel();
private JButton showButton = new JButton("show dialog ..."), okButton = new JButton("OK"),
applyButton = new JButton("Apply"), cancelButton = new JButton("Cancel"); private JButton[] buttons = new JButton[] {
okButton, applyButton, cancelButton, };
private JDialog dialog = new JDialog((Frame)null, // 所有者
"Constraints Dialog",// タイトル
true); // モーダル
public Test() {
14.2 JDialogクラス 31
Container dialogContentPane = dialog.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(showButton); dialogContentPane.add(cp, BorderLayout.CENTER); dialogContentPane.add(buttonsPanel, BorderLayout.SOUTH); dialog.pack(); // ダイアログの配置はそのサイズに基づいて行われるため、 // setLocationRelativeTo()はpack()の後に呼び出す // アプレットはまだ表示されていないため、 // setLocationRelativeTo()をここで呼び出すとダイアログが中央に揃えられて表示される // setLocationRelativeTo()を呼び出さないとダイアログは画面の座標で(0, 0)の位置に表示される // dialog.setLocationRelativeTo(this); for(int i=0; i < buttons.length; ++i) {
buttonsPanel.add(buttons[i]); }
addButtonListeners(); }
private void addButtonListeners() {
showButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
// setLocationRelativeTo()をここで呼び出すと、 // ダイアログはアプレットの範囲を越えて中央に揃えられる dialog.setLocationRelativeTo(Test.this); dialog.show(); } }); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
showStatus("OK button Activated"); dialog.dispose();
} });
applyButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
showStatus("Apply button Activated"); }
});
cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
showStatus("Cancel button Activated"); dialog.dispose(); } }); } } 次に、JDialogクラスについてコンポーネントの概要14-2にまとめる。