2010-08-06 77 views
1

我想實現的是向IProject彈出菜單提供操作。 動作這樣定義在我的plugin.xml:如何設置Eclipse動作貢獻的初始狀態

<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> 

上運行(),我爲了節省菜單切換狀態做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上下文菜單中首先被激活它不能反映保存的狀態,但如果我拿菜單來了它再次顯示了預期的保存狀態。然後,如果我爲其他項目提供菜單,它將再次以不正確的狀態顯示,但第二次工作正常。

回答

0

好,似乎還有要麼是與我在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()

這就是爲什麼我們應該火的SelectionChanged ()每次在setActivePart()內部以確保我們得到最近的選擇:

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

我希望可以幫助別人;)

0

井,看看這些線

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

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

變量「項目」指向所選擇的項目,因此,狀態僅存儲在其元數據。如果要存儲與項目無關的狀態,解決方案可能會將它們存儲在工作空間元數據中。

+0

我想存儲每個項目的菜單切換狀態。 問題是當IProject上下文菜單第一次被激活時,它不能反映已保存的狀態,但是如果我再次使用該菜單,它會按預期顯示已保存的狀態。然後,如果我爲其他項目提供菜單,它將再次以不正確的狀態顯示,但第二次工作正常。 – blablacio 2010-08-07 16:02:44