モデルは中身で (1) [CheckBox付きListを実装する: JList]
2002-01-20
Swingでは、MVC(Model-View-Control)に基づいた実装が広く行われています。MVCを通してSwingを見ていくと、流儀に従って実装を行っていくことで、容易に拡張が可能なことがわかってきます。項目をリストで表示し、それぞれにチェックボックスをつけて、何らかの選択動作ができるGUIを考えてみましょう。
MorePasteでは、[Combination]タグで、チェックボックス機能つきのリストを使用しています。そこでは、ポップアップメニューから選択した項目がリストに追加され、それぞれのチェックボックスで、その項目の有効、無効を設定できるようになっています。これはJListをベースにしているのですが、どのように実装しているか、ちょっと書いてみます。
■できなかったっけ?
Swingで、チェックボックスの並んでいるUIを作成できるものにJMenuがあります。JMenuに、JCheckBoxMenuItemのインスタンスをaddすれば、簡単にチェックボックスのついたメニューを作れます。JMenuとJListは当然、使用の目的が違いますから構造も違うのですが、何となく、チェックボックス機能つきのリストも簡単に実現出来そうな気がしてきます。
Java2
SDKに付属するデモ、SwingSet2のList
Demoでは、チェックボックスつきのリストを使用して、動的にリストを生成する機能を示しています。しかし、ここで使用されているチェックボックス付きのリストは、JPanelにJCheckBoxを並べてJScrollPaneにはめ込んだものです。これでは、実現は出来ても、リスト項目の生成やハンドリングなど、操作がJListとはかなり違います。
結局、JDK 1.3の時点で、リストで表示する標準的なコンポーネントであるJListそのものに、チェックボックスを付加する機能は、標準では付いていません。JavaSoftは、あまり需要がないと判断したのでしょう。
■お手前はいかほど
作成したチェックボックスリストでは、出来る限りJListの機能を使って、ハンドリングの使用感を同じようにしながら、実装を局所化することを考えました。JListはそのまま使用して、ModelとRenderer(Viewにあたる?)に実装を集中させています。このようにするにあたり、JListの実装の流儀を見てみました。
- リストの状態は、ListModelで全て保持
- リストの項目は、JListからは何の意味も持たず、ただ文字列を表示
上記は当然と思われるかもしれませんが、実装の方針を絞り込むための示唆を与えています。JMenuと比較してみます。JMenuはボタンの集まりで、チェックボックスつきの項目は、JCheckBoxMenuItemが保持しています。JMenuにはメニュー項目の状態を管理するModelはありません。反対に、それぞれの項目には、自分の状態を保持することが求められます。
SwingSetのList Demoの実装は、JMenuの実装方式に近いことがわかります。このような実装が効果的な場合は多々ありますし、理解しておくことは重要ですから、頭の片隅に置いておくべきでしょう。しかし、JListとはきわめて距離があることになります。
■どこを作ろか
ということで、チェックボックスのデータを持たせる際には、外部に持たせるのではなく、素直にListModelに持たせた方がJListの流儀には合う、という理解で進めることにします。リストの項目を追加する場合、項目側にチェックボックスの状態を保持することを気にさせなくてもいいようにします。MorePasteのチェックボックス機能つきリストでは、リストを構成する部品として、以下のものを実装しています。
- CheckBoxListModel:
チェックボックスの状態(selected or not)とリスト項目の有効無効(enabled or not)を格納する
- CheckBoxCellRenderer:
チェックボックスつきのリストを描画する
- ListChecker:
チェックボックスがクリックされたかどうか調べて、モデルの状態を変更し、再描画させる
ListCheckerは、本来、CheckBoxListとでもして、その内部で動作させるべき機能です。このように機能を抜き出したのは、JListをそのまま使用すればいいようにするためですが、それと引き換えに初期化で一定のコーリングシーケンスに従う必要が出て来てしまっています。コーリングシーケンスが複雑で、使い勝手が悪くなるようであれば、やはりCheckBoxListクラスを作るべきでしょう。が、今回は、そのようにはしていません。
CheckBoxListModelのチェックの状態で、selectedという言葉を用いています。これは、JCheckBoxと用語を共通にすることを狙っています。JCheckBoxでは、チェックボックスの状態を保持するメソッドにselectedという名称を使ってしまっています。リスト自体のselectionと混同してしまいそうですが、意味することは全く違います。
JCheckBoxはボタンの一種として実装されており、それ自体は、ほとんど独自のメソッドを持っていません。チェックボックスを抽象化して、ボタンとして扱ってしまうのは大胆だと感じますが、それによりほとんど使用感の差を感じないのは、使う上ではとても有効だと思います。チェックボックス付きリストは、このようにできるでしょうか。
それぞれの実装については、次回以降で述べたいと思います。

|