JFace

先日のListViewerに引き続き第二段のList構造を持つViewerを試してみましょう。


その名もTreeViewer!


簡単なDomParserチックなのを作成します。

package jface.list.sample;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DomDocumentContentProvider implements ITreeContentProvider {
	
	public Object[] getChildren(Object parentElement) {
		//子ノードを取り出す。
		return getChildrenNodeArray((Node) parentElement);
	}
	
	public Object getParent(Object element) {
		//親ノードを取り出す。
		return ((Node) element).getParentNode();
	}
	
	public boolean hasChildren(Object element) {
		//子ノードがいるか?
		return ((Node) element).hasChildNodes();
	}
	
	//Nodeの子ノードをNodeの配列にして返すメソッド
	public Object[] getElements(Object inputElement) {
		return getChildrenNodeArray((Node) inputElement);
	}
	
	public void dispose() {
		
	}
	
	public void inputChanged(Viewer viewer, Object oldObject, Object newInput) {
		
	}
	
	private Node[] getChildrenNodeArray(Node node) {
		NodeList nodeList = node.getChildNodes();
		Node[] nodes = new Node[nodeList.getLength()];
		for (int i = 0; i < nodeList.getLength(); i++) {
			nodes[i] = nodeList.item(i);
		}
		return nodes;
	}
}

ITreeContentProviderを実装したクラスを作成ですね。
必要なメソッドをインプリしてやるくらいで特に変わったことはしてません。


で、次は構造を調べるためのXMLを書きます。


sample.xml

<?xml version="1.0" encoding="utf-8" ?>
<parent>
  parent1
  <child>
    children1
    <grandchild>grandchild</grandchild>
    children2
  </child>
  parent2
</parent>

特に意味のないxml文書ですw


で、メインのWindowクラスですね。

package jface.list.sample;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.w3c.dom.Document;

public class TreeViewerSample extends ApplicationWindow {
	private TreeViewer treeViewer;
	
	public TreeViewerSample() {
		super(null);
	}
	
	public static void main(String[] args) {
		TreeViewerSample window = new TreeViewerSample();
		window.setBlockOnOpen(true);
		window.open();
		Display.getCurrent().dispose();
	}
	
	protected Control createContents(Composite parent) {
		treeViewer = new TreeViewer(parent, SWT.NONE);
		//treeViewerにDomDocumentContentProviderをセット
		treeViewer.setContentProvider(new DomDocumentContentProvider());
		
		try {
			//XMLをパースするための準備。
			DocumentBuilderFactory builderFactory =
				DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.parse("sample.xml");
			//パースしてできたものをtreeViewerにセット
			treeViewer.setInput(document);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//treeViewerからツリーを取り出して戻す。
		return treeViewer.getTree();
	}
}

基本は昨日までと一緒でオーバーライドしたメソッドの中で先ほどのxmlファイルを読み込んでパースしたものをtreeVewerにセットしてるだけです。

で、実行!

Tree構造で表示されたかと思います。
jarファイルのVersionで多少動きが異なるみたいです。
3.1は意外とシンプルに出ます。


表示を変更したい方は、LabelProviderを継承したクラスを作って、getText(Object element):Stringをオーバーライド!
戻り値に、((Node) element).getNodeName()でもしてやれば、3.1(正式にどこら辺で変わったかはわからないですが^^;)と同じように表示されます。


っと、その作ったクラスをtreeVewer.setContentProvider()の下辺りに、treeViewer.setLabelProvider(new 自作ラベルプロバイダークラス);と書いて、セットしてあげてください。

この状態だと、タグの間にTextノードが入ってしまいます。

今日はこの辺にしておいて、次回はこれの拡張を行っていこうかなと思います。
(明日じゃなくて次回ってとこが弱気ですが。。。)