ツリービューは、ツリーに表示するデータを保持するために使用します。
カスタムビューの作成
これまでのセクションでは、組み込みのコンテントツリービューだけを使用してきました。 このセクションでは、新たに開発者が独自に作成可能なカスタムビューの作り方について説明します。 これは扱うデータ量が大きいときや、その並び方が複雑な場合に必要になります。 例えば、数千の行を持つツリーで treeitem
要素を使用した場合、パフォーマンス的に実用にならないと思います。 また、表示するデータを計算処理によって作成するような場合にも、カスタムビューによる実装は適しています。 カスタムビューを作成すると、使用するデータの種類に最も適した方法で、データの取得と保存を行うことができます。 このため、たとえ表示対象の行が数十万行あるような場合も、ツリーを利用することが可能になります。
カスタムビューを作成するには、nsITreeView インターフェイスを実装したオブジェクトを作成する必要があります。 このオブジェクトは JavaScript で作成することも可能ですが、ツリーごとに別々のオブジェクトを作成する必要があります。 カスタムツリービューを利用する場合、コンテントツリービューは利用しないので、当然
、treeitem
、treerow
の各要素も使用しません。 カスタムビューは、データを別の所から取得することになるため、treecell
要素は空にしておきます。 以下に例を示します。treechildren
<tree id="my-tree" flex="1"> <treecols> <treecol id="namecol" label="Name" flex="1"/> <treecol id="datecol" label="Date" flex="1"/> </treecols> <treechildren/> </tree>
このツリーに表示するデータを設定するためには、ビューオブジェクトを作成する必要があります。 ビューは、ツリーの各セルの値や行の総数といった情報や、それ以外で付加的に必要な情報をツリーに示すために使用されます。 このため、ツリーは表示に必要な情報の取得のために、ビューのメソッドを呼び出すことになります。
一般的に、ツリービューで実装可能な関数は 30 以上ありますが、必須で実装しなければならないものは、ツリーから呼び出されるものだけになります。 必ず実装する必要がある 3 つのメソッドを、以下に示します。
- rowCount
- このプロパティは、ツリーに含まれる行の総数が設定されている必要があります。
- getCellText( row , column )
-
このメソッドは、指定された行と列に対応するテキストを返す必要があります。このメソッドは、各セルにデータを表示するために呼び出され、このとき、行を表す引数 row には 0 から始まる数が渡されます。また、列を表す引数 column には、対応する
TreeColumn
オブジェクトが渡されます。ただし、(Firefox 1.5/Mozilla 1.8) より古いバージョンでは、列の id 属性の値が渡されます。なお、以前のように id が必要な場合は、TreeColumn
のid
プロパティを利用することができます。 - setTree( tree )
- このメソッドは、一度だけ呼び出され、そのビューに対応する tree 要素を設定します。
以下にツリービューオブジェクトの定義例を示します。 なお、オブジェクトの名前は、好みのもので構いません。
//Moz 1.8 var treeView = { rowCount : 10000, getCellText : function(row,column){ if (column.id == "namecol") return "Row "+row; else return "February 18"; }, setTree: function(treebox){ this.treebox = treebox; }, isContainer: function(row){ return false; }, isSeparator: function(row){ return false; }, isSorted: function(){ return false; }, getLevel: function(row){ return 0; }, getImageSrc: function(row,col){ return null; }, getRowProperties: function(row,props){}, getCellProperties: function(row,col,props){}, getColumnProperties: function(colid,col,props){} };
この例には、最低限ツリーを動作させるためには必須ではないため、上の説明には含まれていない関数がいくつか定義されています。 これらについても、ツリーが付加的な情報の取得のために呼び出すので、上記のように最低限の実装はしておく必要があります。
この例は 10,000 の行を持つツリーの例としても使用することができるもので、 最初の列のセルの内容は、テキスト「Row X」(X は行の番号) になります。 また、2 番目の列のセルの内容は、固定で「February 18」になります。 関数 getCellText()
にある if 文では、引数 column の id
プロパティと、テキスト「namecol
」の比較をしています。 このテキスト「namecol
」は、前の例における最初の
要素の treecol
id
に対応しています。 言うまでもなく、この例はごく単純なもので、実際のアプリケーションでは各セルのデータの扱いはもっと複雑なものになるはずです。
最後にビューオブジェクトとツリーを関連付ける必要があります。 ツリーには view
プロパティがあり、ここに上で作成したビューオブジェクトを設定します。 このプロパティは、いつでもビューの設定のために値を代入したり変更したりすることが可能です。
function setView(){ document.getElementById('my-tree').view = treeView; }
カスタムツリーの例
以下に、これまでの例をまとめたものを示します。 なお、ここでは例を単純にするためにスクリプトをインラインに記述していますが、 通常は外部スクリプトファイルに記述するようにしてください。
例 1 : ソース
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <window title="Tree Example" id="tree-window" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="setView();"> <script> //Moz 1.8 var treeView = { rowCount : 10000, getCellText : function(row,column){ if (column.id == "namecol") return "Row "+row; else return "February 18"; }, setTree: function(treebox){ this.treebox = treebox; }, isContainer: function(row){ return false; }, isSeparator: function(row){ return false; }, isSorted: function(){ return false; }, getLevel: function(row){ return 0; }, getImageSrc: function(row,col){ return null; }, getRowProperties: function(row,props){}, getCellProperties: function(row,col,props){}, getColumnProperties: function(colid,col,props){} }; function setView(){ document.getElementById('my-tree').view = treeView; } </script> <tree id="my-tree" flex="1"> <treecols> <treecol id="namecol" label="Name" flex="1"/> <treecol id="datecol" label="Date" flex="1"/> </treecols> <treechildren/> </tree> </window>
画像から、2 つの列に、それぞれ getCellText()
関数から取得されたデータが表示されていることが確認できます。 また、この例ではビューを設定する setView()
関数を、ウインドウの onload()
ハンドラから呼び出すようにしていますが、 必要ならばもっと遅いタイミングで行ってもかまいません。 なお、ビューはいつでも変更できます。
getCellText()
関数が、実際に内容を表示する必要があるときにのみ呼び出されていることを補足しておきます。 上の 10,000 行の例の場合も、getCellText()
は、そのとき表示中のセルに対してのみ呼び出されています。 この画像では、最後に一部だけ表示されている行も含めて、7 行が表示されているだけなので、 getCellText()
は、7 行 × 2 列で、計 14 回しか呼び出されません。 それ以外の行については、利用者がスクロールを行って、実際に表示されるようになったときに呼び出されます。 この挙動が、ツリーを非常に効率的なものにしています。
ビューオブジェクトは、組み込みのコンテントツリービューを利用するツリーでも利用できることを注記しておきます。 このビューを、セルのラベルなどの情報を取得するために利用することができます。
ツリービューに実装することができる、全てのプロパティと一覧は nsITreeView インターフェイス を参照してください。 このうちのいくつかは、次のセクションで見ていく予定です。
次のセクションでは、ツリービューのさらに高度な使い方について見ていきます。