// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents


SelectionDialogは、ダイアログ上で選択したオブジェクトを取得するメソッドを持った、便利なダイアログクラスです。これ自体は抽象クラスで、これを拡張していろいろなダイアログを作成します。

#ref(dialog.png)

こんな↑パッケージエクスプローラライクなビューワを配置して、その中で選択されたオブジェクトを取得する、なんてダイアログを作ることができます。


**しくみ [#ma0bd5ec]
このクラスで実装されている特徴的なメソッドは
 protected void setResult(List newResult);
 public Object[] getResult();
 public void setInitialSelections(Object[] selectedElements);
 public void setInitialElementSelections(List selectedElements);
あたりです。setResultはユーザが選択したオブジェクトを格納します。SelectionDialogのサブクラスでこのメソッドを呼び出せばよいです。getResultはそのセットしたオブジェクトを取得します。このダイアログをnewした側のクラスから呼び出されるメソッドですね。

setInitialSelections,setInitialElementSelectionsはあらかじめオブジェクトを選択させておきたいときに使用します。



**やってみる [#cb986f97]
上のダイアログを実際に作ってみました。ソースの詳細は[[PackageExplorerSelectionDialog>http://www.masatom.in/viewvc/trunk/nu.mine.kino.plugin.utils/source/nu/mine/kino/plugin/utils/dialogs/PackageExplorerSelectionDialog.java?root=Others&view=log]]にあります。

***コンストラクタ [#e12d9297]
 public PackageExplorerSelectionDialog(Shell parentShell, IAdaptable root, String message) {
   super(parentShell);
   setTitle("リソースの選択");
   this.root = root;
   if (message != null) {
     setMessage(message);
   } else {
     setMessage("リソースを選択します。");
   }
   setShellStyle(getShellStyle() | SWT.RESIZE);
 }

コンストラクタで IAdaptable root を渡してもらいフィールドに格納しています。ここには呼び出し側が
 PackageExplorerSelectionDialog dialog = new PackageExplorerSelectionDialog(
         getShell(), ResourcesPlugin.getWorkspace().getRoot(),null);
などとしてワークスペースを渡しています。

***ダイアログにTreeViewerを配置 [#t53239a3]
また
 protected Control createDialogArea(Composite parent);
では普通(?)にTreeViewerを配置し、そこに
 treeViewer.setInput(((IWorkspaceRoot) root).getProjects());
とプロジェクトの配列を渡しています。setContentProvider、setLabelProviderなどはソース詳細を見てください。

あ、あと
 treeViewer.addFilter(new ViewerFilter() {
   @Override
   public boolean select(Viewer viewer, Object parentElement,
       Object element) {
     if (element instanceof IProject) {
       IProject project = (IProject) element;
       if (!project.isAccessible()) {
         return false;
       }
     }
     return true;
   }
 });
などとして、開いているプロジェクトだけをリストするようにしています。


***Selectionの変更に反応するリスナ [#h6ccd318]
  private ISelectionChangedListener listener = new ISelectionChangedListener() {
    public void selectionChanged(SelectionChangedEvent event) {
      IStructuredSelection sselection = (IStructuredSelection) event
          .getSelection();
      IResource firstElement = (IResource) sselection.getFirstElement();
      if (firstElement.getType() == IResource.FILE) {
        getOkButton().setEnabled(true);
      } else {
        getOkButton().setEnabled(false);
      }
    }
  };
を定義してビューワにリスナを追加し、IResource.FILEの場合だけOKボタンを押せるようにしました。


***OKを押したときの処理 [#t8b36959]
 protected void okPressed() {
   IStructuredSelection selection = (IStructuredSelection) treeViewer
           .getSelection();
   setResult(selection.toList());
   super.okPressed();
 }
と選択されたオブジェクト引数にsetResultを呼び出しています。



***呼び出し側の処理。 [#ubf54e39]
呼び出し側は、
 PackageExplorerSelectionDialog dialog = new PackageExplorerSelectionDialog(
         getShell(), ResourcesPlugin.getWorkspace().getRoot(),null);
のあとにdialogを開き、OKが押されたらオブジェクトをgetResultで取得する、となります。
具体的には
 if (dialog.open() == PackageExplorerSelectionDialog.OK) {
   Object[] result = dialog.getResult();
   if (result.length == 1) {
     IFile file = (IFile) result[0];
   }
 }
とかですね。



このクラスを使えば、いちいちデータを取り出すメソッドや格納するメソッドをダイアログに実装しなくてよいので、結構便利ですね。




----
この記事は
#vote(おもしろかった[4],そうでもない[0])
#vote(おもしろかった[5],そうでもない[0])
- ちなみに上でつくったダイアログはorg.eclipse.ui.dialogs.ResourceSelectionDialogの実装を参考にしました(というかコピペ) -- [[きの]] &new{2007-05-24 (木) 08:10:45};


#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS