2017-07-26 19 views
0

私はherehereを見ましたが、私の質問に対する答えは見つかりませんでした。なぜTreeViewer.refresh()を呼び出すとcontentProviderのgetChildren(Object)メソッドが呼び出されないのですか?

少し背景:

  • 私はEclipseプロジェクト内のリソースのサブセットを表すビューを実装しています。
  • ツリー内のプロジェクトノードは、プロジェクトが開いているかどうかをチェックして、子ノードを含めるべきかどうかを確認します。実際、プロジェクトノードのhasChildren()メソッドはIProject.isOpen()を返します。
  • eclipseビューはresourceChangeEventsにサブスクライブし、のいずれかがに変更された場合、TreeViewerでrefresh()が呼び出されます。その後、

    あなたは木の使用で(引数なし)

    TreeViewer.refresh(); 
    

    refresh()をオブジェクトを追加または削除した場合必要があります。this質問からの情報に基づいて


モデル全体の新しい情報でツリー全体を更新します。コードにブレークポイントを設定することにより


、私はリフレッシュ処理中に、フレームワークがhasChildrenを呼び出すことを発見しました()いくつかのノード上で回、しかし決して通話のGetChildrenメソッド()。

現在、Projectが開いていて、ツリー内でそれを表すノードがいくつかの子で展開されているとします。私はプロジェクトを閉じ、リソース変更イベントが発生します。これにより、refresh()が発生します。尋ねられたとき、projecthasChildren()からfalseを返しますが、まだ子はツリーに存在しています。

逆に、プロジェクトが閉じられていてノードに子がない(拡張矢印がない)場合は、プロジェクトを開くとリソース変更イベントが発生します。refresh()はツリー、プロジェクトノードはhasChildren()からtrueを返します。 getChildren()は、これらの子どもが何であるかを知るために呼び出されることはありません。ノードにはまだ子がなく、拡張矢印はありません。新しいノードが追加され、古いものは削除する場合

は、現在のモデルは、イベントを発生させ、そして木は、これらをリッスンし、適切なTreeViewerに add(Object, Object)remove(Object)を呼び出しますが、モデルは、その子を変更する必要があるかどうかをチェックしますコンテンツプロバイダーのgetChildren()メソッドを介して要求されたときに呼び出されます。

getChildren()hasChildren()から呼び出すと、問題が部分的に緩和されることがありますが、これは面倒なように思えますし、リフレッシュ()の仕組みを理解することで、必要ないはずです。


はなぜTreeViewerのrefresh()方法は、その子が何であるかを確認するためにノードを再照会していないのですか?それがないとすれば、オブジェクトの追加と削除をどのように処理するのですか?

+0

ノードが展開されている場合のみgetChildrenを呼び出します。これは、hasChildren値からの展開/折りたたみインジケーターを表示します。 –

+0

@greg:それは私が起こることが期待されるものです。しかし、 'refresh'にもかかわらず、展開/折りたたみインジケータは' hasChildren'から返された値を反映しません。 –

+0

あなたのコンテンツプロバイダの実装を見せて、視聴者の入力として何が設定されているのかを正確に示す必要があります。 – nitind

答えて

0

それは問題がTreeViewer.setComparerに渡されたIElementComparerの実装は、このように見えたということでしたが判明:

@Override 
public boolean equals(final Object one, final Object two) { 
    if (one.getClass().equals(two.getClass())) { <-- This is not always true... 
     if (one instanceof MyCustomNodeBaseClass) { 
      return ((MyCustomNodeBaseClass) one).isEquivalentTo((MyCustomNodeBaseClass) two); 
     } 
    } 
    return false; <-- ...therefore this is the problem, as it wasn't expected to be reached 
} 

IElementComparer.equals(Object, Object)方法はclass org.eclipse.ui.internal.ViewSiteの引数で呼び出すことができ、そしてあまりにもそれらを処理する必要があります。

静かにパラメータのクラスが認識されないで、問題のある行を置き換えることができた場合にはfalseを返すように疑わしい動きだった:私は最終的にデバッガに従うことによって、これを見つけた

return (one.equals(two)); <-- this will quietly handle unexpected classes better. 

updatePlus()のメソッドAbstractTreeViewer

関連する問題