如何设置Eclipse操作贡献的初始状态

时间:2010-08-06 19:57:56

标签: java eclipse eclipse-plugin action eclipse-rcp

我想要实现的是为IProject弹出菜单提供操作。 这个动作在我的plugin.xml中定义如下:

   <extension
         point="org.eclipse.ui.popupMenus">
      <objectContribution
            adaptable="true"
            objectClass="org.eclipse.core.resources.IProject"
            nameFilter="*"
            id="RemoteSync.contribution1">
         <action
               label="Enable RemoteSync"
               class="remotesync.builder.ToggleNatureAction"
               menubarPath="additions"
               enablesFor="1"
               id="RemoteSync.addRemoveNatureAction"
               style="toggle">
         </action>
      </objectContribution>
   </extension>

在run()上我执行setPersistentProperty()以保存菜单切换状态,我想稍后在插件启动时或者在setActivePart()上显示弹出菜单时恢复。

以下是相关的代码:

public void run(IAction action) {
    if (selection instanceof IStructuredSelection) {
        for (Iterator it = ((IStructuredSelection) selection).iterator(); it
                .hasNext();) {
            Object element = it.next();
            IProject project = null;
            if (element instanceof IProject) {
                project = (IProject) element;
            } else if (element instanceof IAdaptable) {
                project = (IProject) ((IAdaptable) element)
                        .getAdapter(IProject.class);
            }
            if (project != null) {
                toggleNature(project);
                try {
                    ((IResource) project).setPersistentProperty(
                            new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());
                } catch (CoreException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}


public void setActivePart(IAction action, IWorkbenchPart targetPart) {
    if (selection instanceof IStructuredSelection) {
        for (Iterator it = ((IStructuredSelection) selection).iterator(); it
                .hasNext();) {
            Object element = it.next();
            IProject project = null;
            if (element instanceof IProject) {
                project = (IProject) element;
            } else if (element instanceof IAdaptable) {
                project = (IProject) ((IAdaptable) element)
                        .getAdapter(IProject.class);
            }
            if (project != null) {
                toggleNature(project);
                try {
                    String status = ((IResource) project).getPersistentProperty(
                            new QualifiedName("", ENABLED_PROPERTY));
                    action.setChecked(new Boolean(status));
                } catch (CoreException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

一切都按预期工作但有一点 - 当首次激活IProject上下文菜单时,它不会反映已保存的状态,但如果我再次启动菜单,则会按预期显示已保存的状态。然后,如果我将菜单带到另一个项目,它再次显示状态不正确,但第二次工作正常。

2 个答案:

答案 0 :(得分:0)

好吧,看看这些行

            String status = ((IResource) project).getPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY));

      ((IResource) project).setPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());

变量'project'指向所选项目,因此状态仅存储在其元数据中。如果要存储与项目无关的状态,则解决方案可能是将它们存储在工作空间元数据中。

答案 1 :(得分:0)

好吧,似乎我的代码或Eclipse 3.6 I20100608-0911中的bug /功能有问题,这会阻止selectionChanged()在您第一次单击资源时正常触发(在我的情况下为IProject):

public void selectionChanged(IAction action, ISelection selection) {
    this.selection = selection;
}

我发现第一次打开上下文菜单时会按此顺序触发事件:

  1. 的SelectionChanged()
  2. setActivePart()
  3. 的SelectionChanged()
  4. 第一次传递给selectionChanged()的ISelection总是“空选”。

    第一次之后,使用上下文菜单会产生以下触发事件的顺序:

    1. setActivePart()
    2. 的SelectionChanged()
    3. 这就是为什么我们每次都应该在setActivePart()内部激活selectionChanged()以确保我们获得最新的选择:

      public void setActivePart(IAction action, IWorkbenchPart targetPart) {
          selectionChanged(action, targetPart.getSite().getPage().getSelection());
          ...
      }
      

      我希望能帮到某人;)