2017-08-23 5 views
1

RCPアプリケーションには、CommonNavigatorクラスを拡張するビューがあります。アプリケーションのワークスペース内のプロジェクトは、ディスク上の場所によって異なるアイコンを表示する必要があります。ワークスペース内にローカルに存在するプロジェクトは、インポートされたプロジェクトとは異なるアイコンを持つ必要があります。RCPアプリケーションのプロジェクトの性質を変更する

Iはplugin.xmlの中で2つのプロジェクトの性質を定義することによって、これを実現:MyProjectNatureと異なるアイコンでMyProjectNatureImported以下の方法で相応の性質の間で変化する:

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

リスナーがこれ以上変更できないように、リソース変更イベントが送信されている間、ワークスペースがロックされます。

スケジューリング・ルールを使用して、リスナーからジョブを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

プロジェクトの性質が間違っています。あなたの実際の問題は余分な仕事で回避することができますが、それはプロジェクトの性質が異なるイメージを達成するための間違った手段である可能性があるという指標です。

ローカルプロジェクトやインポートプロジェクトのような違いを強調する指定方法は、デコレータです。デコレータを使用すると、表示されている場所に関係なく、要素のイメージやテキストを(ほとんどの場合)装飾したり、交換したりすることができます。

関連する問題