diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java index 6e5167e698c..0063b9a5c3a 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java @@ -21,6 +21,8 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -29,7 +31,10 @@ import org.eclipse.jdt.testplugin.JavaProjectHelper; import org.eclipse.jdt.testplugin.JavaTestPlugin; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -54,6 +59,7 @@ import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider; import org.eclipse.jdt.internal.ui.util.CoreUtility; @@ -212,9 +218,25 @@ public void testDeleteBottomLevelFragmentFolding() throws Exception { protected void sendEvent(IJavaElementDelta delta) { IElementChangedListener listener= (IElementChangedListener) fProvider; listener.elementChanged(new ElementChangedEvent(delta, ElementChangedEvent.POST_CHANGE)); - - //force events from dispaly - while(fMyPart.getTreeViewer().getControl().getDisplay().readAndDispatch()) { + CountDownLatch latch = new CountDownLatch(1); + new Thread(new Runnable() { + + @Override + public void run() { + try { + Job.getJobManager().join(PackageExplorerContentProvider.class, new NullProgressMonitor()); + } catch (OperationCanceledException | InterruptedException e) { + } + latch.countDown(); + } + }).start(); + //force events from display + try { + while(!latch.await(10, TimeUnit.MILLISECONDS)) { + while(fMyPart.getTreeViewer().getControl().getDisplay().readAndDispatch()) { + } + } + } catch (InterruptedException e) { } } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/packageview/PackageExplorerContentProvider.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/packageview/PackageExplorerContentProvider.java index 2e50c4ba7cc..dd812f56109 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/packageview/PackageExplorerContentProvider.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/packageview/PackageExplorerContentProvider.java @@ -18,6 +18,8 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; @@ -28,6 +30,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -93,6 +96,8 @@ public class PackageExplorerContentProvider extends StandardJavaElementContentPr private UIJob fUpdateJob; + private final DeltaJob fdeltaJob; + /** * We use a cache to know whether a package has a single child for the hierarchical representation. * This avoids looping over all packages for each call to @@ -107,6 +112,7 @@ public class PackageExplorerContentProvider extends StandardJavaElementContentPr */ public PackageExplorerContentProvider(boolean provideMembers) { super(provideMembers); + fdeltaJob= new DeltaJob(); fShowLibrariesNode= false; fIsFlatLayout= false; fFoldPackages= arePackagesFoldedInHierarchicalLayout(); @@ -127,6 +133,12 @@ protected Object getViewerInput() { @Override public void elementChanged(final ElementChangedEvent event) { + IJavaElementDelta delta= event.getDelta(); + fdeltaJob.queue.add(delta); + fdeltaJob.schedule(); + } + + protected void processDelta(IJavaElementDelta delta) { final ArrayList runnables= new ArrayList<>(); try { clearPackageCache(); @@ -136,7 +148,7 @@ public void elementChanged(final ElementChangedEvent event) { if (inputDeleted(runnables)) return; - processDelta(event.getDelta(), runnables); + processDelta(delta, runnables); } catch (JavaModelException e) { JavaPlugin.log(e); } finally { @@ -1006,4 +1018,29 @@ public void propertyChange(PropertyChangeEvent event) { } } } + + private final class DeltaJob extends Job { + private Queue queue= new ConcurrentLinkedQueue<>(); + + DeltaJob() { + super(PackagesMessages.PackageExplorerContentProvider_update_job_description); + setSystem(true); + } + + @Override + public boolean belongsTo(Object family) { + return family == PackageExplorerContentProvider.class; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + + IJavaElementDelta delta; + while ((delta= queue.poll()) != null) { + processDelta(delta); + } + return Status.OK_STATUS; + } + + } }