2017-08-23 72 views
1

我在我的RCP應用程序中有一個擴展了CommonNavigator類的View。我的應用程序工作區中的項目應根據它們在磁盤上的位置具有不同的圖標:工作區中本地存在的項目應該與導入的項目具有不同的圖標。 MyProjectNature並用不同的圖標MyProjectNatureImported並用下面的方法相應地性質之間改變:在RCP應用程序中更改項目性質

我通過定義在plugin.xml 2項目性質意識到這

private void updateProjectNature(final IWorkspace lf_workspace) 
{ 
    String l_workspacePath = lf_workspace.getRoot().getLocation().toString(); 
    IProject[] l_projectsInWorkspace = lf_workspace.getRoot().getProjects(); 
    for (IProject l_project : l_projectsInWorkspace) 
    { 
     try 
     { 
      File l_projectFile = new File(l_workspacePath + l_project.getFullPath().toString()); 
      final IProjectDescription l_projectDescription = l_project.getDescription(); 
      final String[] l_currentNatures = l_projectDescription.getNatureIds(); 
      final String[] l_newNatures = new String[l_currentNatures.length]; 

      int l_index = 0; 
      if (l_projectFile.exists()) 
      { 
       for (String l_nature : l_currentNatures) 
       { 
        if (l_nature.equals(MyProjectNatureImported.NATURE_ID)) 
        { 
         l_newNatures[l_index] = MyProjectNature.NATURE_ID; 
        } 
        else 
        { 
         l_newNatures[l_index] = l_nature; 
        } 
        l_index++; 
       } 
      } 
      else 
      { 
       for (String l_nature : l_currentNatures) 
       { 
        if (l_nature.equals(MyProjectNature.NATURE_ID)) 
        { 
         l_newNatures[l_index] = MyProjectNatureImported.NATURE_ID; 
        } 
        else 
        { 
         l_newNatures[l_index] = l_nature; 
        } 
        l_index++; 
       } 
      } 
      l_projectDescription.setNatureIds(l_newNatures); 
      l_project.setDescription(l_projectDescription, null); 
     } 
     catch (CoreException e) 
     { 
      LOGGER.warning("Error when setting the project nature of the project " + l_project.getName() + ": " + e.getMessage()); 
     } 
    } 
} 

當我調用從ResourceChangeListener此方法我添加到工作區,我得到它鎖定每一個項目的錯誤,不能editted:

final IWorkspace lf_workspace = ResourcesPlugin.getWorkspace(); 
    lf_workspace.addResourceChangeListener(new IResourceChangeListener() 
    { 
     @Override 
     public void resourceChanged(IResourceChangeEvent event) 
     { 
      updateProjectNature(lf_workspace); 
     } 
    }); 

但是,當我創建一個運行每個幾秒工作,那麼它的工作原理:

Job l_testJob = new Job("Update navigator") 
    { 
     @Override 
     protected IStatus run(IProgressMonitor monitor) 
     { 
      updateProjectNature(lf_workspace); 
      schedule(1000); 
      return Status.OK_STATUS; 
     } 

     @Override 
     public boolean shouldSchedule() 
     { 
      // Check if the job should be scheduled/executed or not 
      return !PlatformUI.getWorkbench().isClosing(); 
     } 
    }; 

    l_testJob.schedule(1000); 

我想調用時才更改到工作區做出,而不是每一秒(節省資源)的方法,但我不明白爲什麼我得到的錯誤,無法改變從性質聆聽者在離開工作的同時沒有任何問題。

任何想法?

回答

1

當發送資源更改事件時,工作空間被鎖定,以便偵聽器無法進行任何更改。

您應該能夠使用調度規則從您的偵聽器提交單個作業,以延遲作業,直到工作空間可用。您應該使用WorkspaceJob以確保更新是原子性的。

class UpdateNatureJob extends WorkspaceJob 
{ 
    UpdateNatureJob() 
    { 
    // Scheduling rule 
    setRule(ResourcesPlugin.getWorkspace().getRoot()); 
    } 

    @Override 
    public IStatus runInWorkspace(final IProgressMonitor monitor) 
    { 
    ... your nature update 

    return Status.OK_STATUS; 
    } 
} 
0

您在濫用項目性質。雖然您的實際問題可以通過額外的工作來解決,但這表明項目性質可能是實現不同圖像的錯誤方法。

強調像本地和導入項目這些差異的指定方式是裝飾器。裝飾器允許您裝飾或交換元素的圖像和文本(幾乎),而不管它在何處顯示。

相關問題