mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
do more work outside EDT, do not stop progress indicator until all usages inserted into the tree
This commit is contained in:
+29
-32
@@ -402,42 +402,39 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
severity, problemDescriptor.isAfterEndOfLine(), null, isFileLevel);
|
||||
}
|
||||
|
||||
private final TransferToEDTQueue<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>> myTransferToEDTQueue;
|
||||
{
|
||||
myTransferToEDTQueue =
|
||||
new TransferToEDTQueue<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>>(new Processor<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>>() {
|
||||
private final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile();
|
||||
private final InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject);
|
||||
private final List<HighlightInfo> infos = new ArrayList<HighlightInfo>(2);
|
||||
private final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
@Override
|
||||
public boolean process(Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator> trinity) {
|
||||
ProgressIndicator indicator = trinity.getThird();
|
||||
if (indicator.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
private final TransferToEDTQueue<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>> myTransferToEDTQueue
|
||||
= new TransferToEDTQueue<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>>("Apply inspection results", new Processor<Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator>>() {
|
||||
private final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile();
|
||||
private final InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject);
|
||||
private final List<HighlightInfo> infos = new ArrayList<HighlightInfo>(2);
|
||||
private final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
@Override
|
||||
public boolean process(Trinity<ProblemDescriptor, LocalInspectionTool,ProgressIndicator> trinity) {
|
||||
ProgressIndicator indicator = trinity.getThird();
|
||||
if (indicator.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProblemDescriptor descriptor = trinity.first;
|
||||
LocalInspectionTool tool = trinity.second;
|
||||
PsiElement psiElement = descriptor.getPsiElement();
|
||||
if (psiElement == null) return true;
|
||||
PsiFile file = psiElement.getContainingFile();
|
||||
Document thisDocument = documentManager.getDocument(file);
|
||||
ProblemDescriptor descriptor = trinity.first;
|
||||
LocalInspectionTool tool = trinity.second;
|
||||
PsiElement psiElement = descriptor.getPsiElement();
|
||||
if (psiElement == null) return true;
|
||||
PsiFile file = psiElement.getContainingFile();
|
||||
Document thisDocument = documentManager.getDocument(file);
|
||||
|
||||
HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity();
|
||||
HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity();
|
||||
|
||||
infos.clear();
|
||||
createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, psiElement);
|
||||
for (HighlightInfo info : infos) {
|
||||
final EditorColorsScheme colorsScheme = getColorsScheme();
|
||||
UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset,
|
||||
info, colorsScheme, getId());
|
||||
}
|
||||
infos.clear();
|
||||
createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, psiElement);
|
||||
for (HighlightInfo info : infos) {
|
||||
final EditorColorsScheme colorsScheme = getColorsScheme();
|
||||
UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset,
|
||||
info, colorsScheme, getId());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}, myProject.getDisposed());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, myProject.getDisposed(), 200);
|
||||
|
||||
private final Set<TextRange> emptyActionRegistered = Collections.synchronizedSet(new HashSet<TextRange>());
|
||||
|
||||
|
||||
+6
-5
@@ -27,14 +27,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Usage: {@link #offer(Object)} } : schedules element for processing in a pooled thread
|
||||
*/
|
||||
public class TransferToPooledThreadQueue<T> extends TransferToEDTQueue<T> {
|
||||
|
||||
public TransferToPooledThreadQueue(@NotNull Processor<T> processorInEDT, @NotNull Condition<?> shutUpCondition) {
|
||||
super(processorInEDT, shutUpCondition);
|
||||
public TransferToPooledThreadQueue(@NotNull String name,
|
||||
@NotNull Processor<T> processorInEDT,
|
||||
@NotNull Condition<?> shutUpCondition,
|
||||
int maxUnitOfWorkThresholdMs) {
|
||||
super(name, processorInEDT, shutUpCondition, maxUnitOfWorkThresholdMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void schedule(Runnable updateRunnable) {
|
||||
protected void schedule(@NotNull Runnable updateRunnable) {
|
||||
JobScheduler.getScheduler().execute(updateRunnable);
|
||||
//ApplicationManager.getApplication().executeOnPooledThread(updateRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -76,7 +76,8 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
|
||||
private final Alarm updateEncodingFromContent = new Alarm(Alarm.ThreadToUse.OWN_THREAD, this);
|
||||
private static final Key<Charset> CACHED_CHARSET_FROM_CONTENT = Key.create("CACHED_CHARSET_FROM_CONTENT");
|
||||
|
||||
private final TransferToPooledThreadQueue<Reference<Document>> myChangedDocuments = new TransferToPooledThreadQueue<Reference<Document>>(new Processor<Reference<Document>>() {
|
||||
private final TransferToPooledThreadQueue<Reference<Document>> myChangedDocuments = new TransferToPooledThreadQueue<Reference<Document>>(
|
||||
"Loading documents", new Processor<Reference<Document>>() {
|
||||
@Override
|
||||
public boolean process(Reference<Document> ref) {
|
||||
Document document = ref.get();
|
||||
@@ -84,7 +85,7 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
|
||||
handleDocument(document);
|
||||
return true;
|
||||
}
|
||||
}, ApplicationManager.getApplication().getDisposed());
|
||||
}, ApplicationManager.getApplication().getDisposed(), -1); // drain the whole queue, do not reschedule
|
||||
|
||||
public EncodingManagerImpl(EditorFactory editorFactory) {
|
||||
editorFactory.getEventMulticaster().addDocumentListener(new DocumentAdapter() {
|
||||
|
||||
@@ -225,7 +225,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
}
|
||||
});
|
||||
}
|
||||
myTransferToEDTQueue = new TransferToEDTQueue<Usage>(new Processor<Usage>() {
|
||||
myTransferToEDTQueue = new TransferToEDTQueue<Usage>("Insert usages", new Processor<Usage>() {
|
||||
@Override
|
||||
public boolean process(Usage usage) {
|
||||
appendUsage(usage);
|
||||
@@ -236,7 +236,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
public boolean value(Object o) {
|
||||
return isDisposed || project.isDisposed() || com.intellij.usages.UsageViewManager.getInstance(project).searchHasBeenCancelled();
|
||||
}
|
||||
});
|
||||
},200);
|
||||
}
|
||||
|
||||
private void setupCentralPanel() {
|
||||
@@ -639,7 +639,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
return indicator == null || !indicator.isCanceled();
|
||||
}
|
||||
});
|
||||
|
||||
drainQueuedUsageNodes();
|
||||
setSearchInProgress(false);
|
||||
}
|
||||
});
|
||||
@@ -666,14 +666,23 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
public void appendUsageLater(@NotNull Usage usage) {
|
||||
myTransferToEDTQueue.offer(usage);
|
||||
}
|
||||
|
||||
public void drainQueuedUsageNodes() {
|
||||
assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myTransferToEDTQueue.drain();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private volatile boolean myIsFirstVisibleUsageFound = false;
|
||||
|
||||
public void appendUsage(@NotNull Usage usage) {
|
||||
doAppendUsage(usage);
|
||||
}
|
||||
|
||||
public UsageNode doAppendUsage(Usage usage) {
|
||||
public UsageNode doAppendUsage(@NotNull Usage usage) {
|
||||
// invoke in ReadAction to be be sure that usages are not invalidated while the tree is being built
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
if (!usage.isValid()) {
|
||||
@@ -747,7 +756,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
return myUsageNodes.size();
|
||||
}
|
||||
|
||||
public void setContent(Content content) {
|
||||
public void setContent(@NotNull Content content) {
|
||||
myContent = content;
|
||||
content.setDisposer(this);
|
||||
}
|
||||
@@ -760,7 +769,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNodeValidity(DefaultMutableTreeNode node) {
|
||||
private void checkNodeValidity(@NotNull DefaultMutableTreeNode node) {
|
||||
Enumeration enumeration = node.children();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
checkNodeValidity((DefaultMutableTreeNode)enumeration.nextElement());
|
||||
@@ -823,7 +832,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
}
|
||||
}
|
||||
|
||||
private void showNode(final UsageNode node) {
|
||||
private void showNode(@NotNull final UsageNode node) {
|
||||
if (!myPresentation.isDetachedMode()) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
@@ -851,9 +860,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
final String commandName,
|
||||
final String cannotMakeString,
|
||||
@NotNull String shortDescription) {
|
||||
|
||||
addButtonToLowerPane(new MyPerformOperationRunnable(cannotMakeString, processRunnable, commandName),
|
||||
shortDescription);
|
||||
addButtonToLowerPane(new MyPerformOperationRunnable(cannotMakeString, processRunnable, commandName), shortDescription);
|
||||
}
|
||||
|
||||
private boolean allTargetsAreValid() {
|
||||
@@ -881,6 +888,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
!ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(VfsUtil.toVirtualFileArray(readOnlyUsages)).hasReadonlyFiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<Usage> getReadOnlyUsages() {
|
||||
final Set<Usage> result = new THashSet<Usage>();
|
||||
final Set<Map.Entry<Usage,UsageNode>> usages = myUsageNodes.entrySet();
|
||||
@@ -894,6 +902,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<VirtualFile> getReadOnlyUsagesFiles() {
|
||||
Set<Usage> usages = getReadOnlyUsages();
|
||||
Set<VirtualFile> result = new THashSet<VirtualFile>();
|
||||
@@ -987,7 +996,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
return usages;
|
||||
}
|
||||
|
||||
private static void collectUsages(DefaultMutableTreeNode node, Set<Usage> usages) {
|
||||
private static void collectUsages(@NotNull DefaultMutableTreeNode node, @NotNull Set<Usage> usages) {
|
||||
if (node instanceof UsageNode) {
|
||||
UsageNode usageNode = (UsageNode)node;
|
||||
final Usage usage = usageNode.getUsage();
|
||||
@@ -1022,7 +1031,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Navigatable getNavigatableForNode(DefaultMutableTreeNode node) {
|
||||
private static Navigatable getNavigatableForNode(@NotNull DefaultMutableTreeNode node) {
|
||||
Object userObject = node.getUserObject();
|
||||
if (userObject instanceof Navigatable) {
|
||||
final Navigatable navigatable = (Navigatable)userObject;
|
||||
@@ -1058,7 +1067,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
private class MyPanel extends JPanel implements TypeSafeDataProvider, OccurenceNavigator,Disposable {
|
||||
@Nullable private OccurenceNavigatorSupport mySupport;
|
||||
|
||||
private MyPanel(JTree tree) {
|
||||
private MyPanel(@NotNull JTree tree) {
|
||||
mySupport = new OccurenceNavigatorSupport(tree) {
|
||||
protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) {
|
||||
if (node.getChildCount() > 0) return null;
|
||||
@@ -1208,7 +1217,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
private final Usage myUsage;
|
||||
private final boolean mySelected;
|
||||
|
||||
private UsageState(final Usage usage, boolean isSelected) {
|
||||
private UsageState(@NotNull Usage usage, boolean isSelected) {
|
||||
myUsage = usage;
|
||||
mySelected = isSelected;
|
||||
}
|
||||
|
||||
@@ -158,11 +158,9 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
catch (ProcessCanceledException e) {
|
||||
//ignore
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
runnable.endSearchForUsages();
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
finally {
|
||||
runnable.endSearchForUsages();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -335,43 +333,45 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
}
|
||||
|
||||
private void endSearchForUsages() {
|
||||
assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
|
||||
int usageCount = myUsageCountWithoutDefinition.get();
|
||||
if (usageCount == 0 && myProcessPresentation.isShowNotFoundMessage()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
|
||||
final String message = UsageViewBundle.message("dialog.no.usages.found.in",
|
||||
StringUtil.decapitalize(myPresentation.getUsagesString()),
|
||||
myPresentation.getScopeText());
|
||||
public void run() {
|
||||
final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
|
||||
final String message = UsageViewBundle.message("dialog.no.usages.found.in",
|
||||
StringUtil.decapitalize(myPresentation.getUsagesString()),
|
||||
myPresentation.getScopeText());
|
||||
|
||||
if (notFoundActions == null || notFoundActions.isEmpty()) {
|
||||
ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, MessageType.INFO,
|
||||
XmlStringUtil.escapeString(message),
|
||||
IconLoader.getIcon("/actions/find.png"), null);
|
||||
}
|
||||
else {
|
||||
List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
|
||||
titles.add(UsageViewBundle.message("dialog.button.ok"));
|
||||
for (Action action : notFoundActions) {
|
||||
Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
|
||||
if (value == null) value = action.getValue(Action.NAME);
|
||||
|
||||
titles.add((String)value);
|
||||
if (notFoundActions == null || notFoundActions.isEmpty()) {
|
||||
ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, MessageType.INFO,
|
||||
XmlStringUtil.escapeString(message),
|
||||
IconLoader.getIcon("/actions/find.png"), null);
|
||||
}
|
||||
else {
|
||||
List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
|
||||
titles.add(UsageViewBundle.message("dialog.button.ok"));
|
||||
for (Action action : notFoundActions) {
|
||||
Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
|
||||
if (value == null) value = action.getValue(Action.NAME);
|
||||
|
||||
int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
|
||||
ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
|
||||
titles.add((String)value);
|
||||
}
|
||||
|
||||
if (option > 0) {
|
||||
notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
|
||||
int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
|
||||
ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
|
||||
|
||||
if (option > 0) {
|
||||
notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());
|
||||
}
|
||||
else if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
Usage usage = myFirstUsage.get();
|
||||
if (usage.canNavigate()) {
|
||||
usage.navigate(true);
|
||||
@@ -382,7 +382,10 @@ public class UsageViewManagerImpl extends UsageViewManager {
|
||||
}
|
||||
else {
|
||||
final UsageViewImpl usageView = myUsageViewRef.get();
|
||||
if (usageView != null) usageView.setSearchInProgress(false);
|
||||
if (usageView != null) {
|
||||
usageView.drainQueuedUsageNodes();
|
||||
usageView.setSearchInProgress(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (myListener != null) {
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -30,13 +31,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* Usage: {@link TransferToEDTQueue#offer(Object)} } : schedules element for processing in EDT (via invokeLater)
|
||||
*/
|
||||
public class TransferToEDTQueue<T> {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
private final String myName;
|
||||
private final Processor<T> myProcessor;
|
||||
private volatile boolean stopped;
|
||||
private final Condition<?> myShutUpCondition;
|
||||
private final int myMaxUnitOfWorkThresholdMs; //-1 means indefinite
|
||||
|
||||
private final Queue<T> myQueue = new ConcurrentLinkedQueue<T>();
|
||||
private final AtomicBoolean invokeLaterScheduled = new AtomicBoolean();
|
||||
private static final long MAX_UNIT_OF_WORK_THRESHOLD_MS = 200; // no more than 200 ms delay
|
||||
private final Runnable myUpdateRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -49,15 +52,14 @@ public class TransferToEDTQueue<T> {
|
||||
long start = System.currentTimeMillis();
|
||||
int processed = 0;
|
||||
while (true) {
|
||||
T thing = myQueue.poll();
|
||||
if (thing == null) break;
|
||||
if (!myProcessor.process(thing)) {
|
||||
stop();
|
||||
return;
|
||||
if (processNext()) {
|
||||
processed++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
processed++;
|
||||
long finish = System.currentTimeMillis();
|
||||
if (finish - start > MAX_UNIT_OF_WORK_THRESHOLD_MS) break;
|
||||
if (myMaxUnitOfWorkThresholdMs != -1 && finish - start > myMaxUnitOfWorkThresholdMs) break;
|
||||
}
|
||||
if (!myQueue.isEmpty()) {
|
||||
scheduleUpdate();
|
||||
@@ -65,9 +67,21 @@ public class TransferToEDTQueue<T> {
|
||||
}
|
||||
};
|
||||
|
||||
public TransferToEDTQueue(@NotNull Processor<T> processorInEDT, @NotNull Condition<?> shutUpCondition) {
|
||||
myProcessor = processorInEDT;
|
||||
private boolean processNext() {
|
||||
T thing = myQueue.poll();
|
||||
if (thing == null) return false;
|
||||
if (!myProcessor.process(thing)) {
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public TransferToEDTQueue(@NotNull @NonNls String name, @NotNull Processor<T> processor, @NotNull Condition<?> shutUpCondition, int maxUnitOfWorkThresholdMs) {
|
||||
myName = name;
|
||||
myProcessor = processor;
|
||||
myShutUpCondition = shutUpCondition;
|
||||
myMaxUnitOfWorkThresholdMs = maxUnitOfWorkThresholdMs;
|
||||
}
|
||||
|
||||
public void offer(@NotNull T thing) {
|
||||
@@ -76,12 +90,12 @@ public class TransferToEDTQueue<T> {
|
||||
}
|
||||
|
||||
private void scheduleUpdate() {
|
||||
if (invokeLaterScheduled.compareAndSet(false, true)) {
|
||||
if (!stopped && invokeLaterScheduled.compareAndSet(false, true)) {
|
||||
schedule(myUpdateRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
protected void schedule(Runnable updateRunnable) {
|
||||
protected void schedule(@NotNull Runnable updateRunnable) {
|
||||
SwingUtilities.invokeLater(updateRunnable);
|
||||
}
|
||||
|
||||
@@ -89,4 +103,20 @@ public class TransferToEDTQueue<T> {
|
||||
stopped = true;
|
||||
myQueue.clear();
|
||||
}
|
||||
|
||||
// process all queue in current thread
|
||||
public void drain() {
|
||||
int processed = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
while (true) {
|
||||
if (processNext()) {
|
||||
processed++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
long finish = System.currentTimeMillis();
|
||||
int i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user