【问题标题】:How to set initial state of an Eclipse action contribution如何设置 Eclipse 动作贡献的初始状态
【发布时间】:2012-04-12 02:35:31
【问题描述】:

我想要实现的是为 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 上下文菜单首次激活时,它不会反映已保存的状态,但如果我再次打开菜单,它会按预期显示已保存的状态。然后,如果我为另一个项目打开菜单,它会再次显示不正确的状态,但第二次工作正常。

【问题讨论】:

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


    【解决方案1】:

    好吧,看看这些行

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

    变量“项目”指向所选项目,因此状态仅存储在其元数据中。如果您想存储独立于项目的状态,解决方案可能会将它们存储在工作区元数据中。

    【讨论】:

    • 我想在每个项目的基础上存储菜单切换状态。问题是当 IProject 上下文菜单第一次被激活时,它不会反映保存的状态,但是如果我再次打开菜单,它会按预期显示保存的状态。然后,如果我为另一个项目打开菜单,它会再次显示不正确的状态,但第二次工作正常。
    【解决方案2】:

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

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

    当我第一次调出上下文菜单时,我发现事件是按此顺序触发的:

    1. selectionChanged()
    2. setActivePart()
    3. selectionChanged()

    第一次传递给 selectionChanged() 的 ISelection 总是“空选择”。

    在第一次之后,打开上下文菜单会产生以下事件触发顺序:

    1. setActivePart()
    2. selectionChanged()

    这就是为什么我们每次都应该在 setActivePart() 中触发 selectionChanged() 以确保我们获得最新的选择:

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

    我希望对某人有所帮助;)

    【讨论】:

      猜你喜欢
      • 2011-02-18
      • 2021-03-10
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多