TreeViewerクラスは、TreeウィジェットをViewer Frameworkで抽象的に操作するためのクラスです。 Viewer Frameworkについての説明はすでにしましたが、 そこで説明されているListViewerは、ファイルシステムの木構造の表示には不向きです。 木構造の表示には、TreeViewerを使います。
TreeViewerにセットするIContentProvider実装クラスについて説明します。
TreeViewerでは、ContentViewer#setContentProviderメソッドで指定するIContentProviderは、 ITreeContentProviderインターフェイスも実装していなければなりません。
getChildrenメソッドは、各要素(ここではファイル)の子を取得するためのメソッドです。 getParentメソッドは、各要素から親要素を取得するためのメソッドです。
hasChildrenメソッドは、引数elementにさらに子要素が存在するかどうかを算出 します。わからないときは常にtrueを返してもいいです。 その場合、フレームワークがgetChildrenメソッドの戻り値で適切に判断しますが、 処理効率的には悪くなります。
getElementsメソッドはIStructuredContentProviderインターフェイスのメソッドです。 処理内容は、一番上の層として表示される要素を決定すること でした。 FileTreeContentProviderでは、Cドライブ直下のファイルやフォルダを取得します。 TreeViewerもやはりStructuredViewerクラスのサブクラスなので、この実装が必要です。
import java.io.File;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
public class FileTreeContentProvider implements ITreeContentProvider {
public Object[] getChildren(Object parentElement) {
return ((File)parentElement).listFiles();
}
public Object getParent(Object element) {
return ((File)element).getParentFile();
}
public boolean hasChildren(Object element) {
File file = ((File)element);
File[] result = file.listFiles();
if (result == null) {
return false;
} else {
return result.length > 0;
}
}
public Object[] getElements(Object inputElement) {
return ((File)inputElement).listFiles();
}
public void dispose() {
}
public void inputChanged(
Viewer viewer,
Object oldInput,
Object newInput) {
}
}
FileLabelProviderクラスは、こちらのサンプルと変わりありません。
import java.io.File;
import org.eclipse.jface.viewers.LabelProvider;
public class FileLabelProvider extends LabelProvider {
public String getText(Object element) {
return ((File)element).getName();
}
}
さて今回は、ダブルクリックに対するリスナ(IDoubleClickListener)の実装クラスを用意しました。 doubleClickメソッドで取得するDoubleClickEventオブジェクトには、getSelectionメソッドが用意されています。 このメソッドはISelection型のオブジェクトを返すのですが、StructurevViewerクラスのサブクラスから発生するイベントオブジェクトから取得した ISelectionオブジェクトは、StructuredSelectionにキャストすることができます。 StructuredSelectionオブジェクトには、セレクトされているアイテム情報を取得することができるメソッドが定義されています 。
import java.io.File;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Label;
public class FullPathDisplayListener implements IDoubleClickListener {
Label label;
public FullPathDisplayListener(Label label) {
this.label = label;
}
public void doubleClick(DoubleClickEvent event) {
File file = (File)((StructuredSelection)event.getSelection()).getFirstElement();
label.setText(file.getAbsolutePath());
}
}
今回のサンプルではSWT.SINGLEスタイルのTreeViewerなので、選択されているのは1つのみです。
なので、getFirstElementメソッドで選択されているアイテムの最初のものを取得するだけで事足りています。
そしてメインのクラスです。 TreeViewerを作成して、そこにFileLabelProviderクラス、FileTreeContentProviderクラス、をセットします。 アイテムがダブルクリックされたときの処理を記述した、FullPathDisplayListenerもセットしています。
import java.io.File;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class TreeViewerComposite extends Composite {
public TreeViewerComposite(Composite parent, File treeRoot) {
super(parent, SWT.NONE);
setLayout(new RowLayout(SWT.VERTICAL));
TreeViewer treeViewer = new TreeViewer(this,
SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
treeViewer.setLabelProvider(new FileLabelProvider());
treeViewer.setContentProvider(new FileTreeContentProvider());
treeViewer.setInput(treeRoot);
Label labelFullPathDisplay = new Label(this, SWT.NONE);
treeViewer.addDoubleClickListener(
new FullPathDisplayListener(labelFullPathDisplay));
labelFullPathDisplay.setLayoutData(new RowData(500, 20));
treeViewer.getControl().setLayoutData(new RowData(500, 450));
setSize(500, 500);
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
File treeRoot = new File("C:/");
TreeViewerComposite tvComp =
new TreeViewerComposite(shell, treeRoot);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
実行結果です。
