mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ProgressManager - always invoke Task callbacks
* add onError() / onFinished() callback
* always trigger one of onSuccess()/onCancel()/onError() and onFinished()
before this change, callbacks hadling was not guaranteed if Task.run() throwed an exception.
Task.Modal - runProcessWithProgressSynchronously() would call onCancel()
Task.Backgroundable - runProcessWithProgressAsynchronously() would do nothing
thus, previous implementation of onFinished() was not error-prone.
* this change might break implementations, that relied on old behaviour of Task.Modal.
This commit is contained in:
committed by
Aleksey Pivovarov
parent
5f33787fb1
commit
5c4046a522
@@ -61,19 +61,32 @@ public abstract class Task implements TaskInfo, Progressive {
|
||||
|
||||
/**
|
||||
* This callback will be invoked on AWT dispatch thread.
|
||||
*
|
||||
* Callback executed when run() throws {@link ProcessCanceledException} or if its {@link ProgressIndicator} was canceled.
|
||||
*/
|
||||
public void onCancel() {
|
||||
onFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback will be invoked on AWT dispatch thread.
|
||||
*/
|
||||
public void onSuccess() {
|
||||
onFinished();
|
||||
}
|
||||
|
||||
protected void onFinished() {}
|
||||
/**
|
||||
* This callback will be invoked on AWT dispatch thread.
|
||||
*
|
||||
* Callback executed when run() throws an exception (except PCE).
|
||||
*/
|
||||
public void onError(@NotNull Exception error) {
|
||||
LOG.error(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback will be invoked on AWT dispatch thread, after other specific handlers
|
||||
*/
|
||||
public void onFinished() {
|
||||
}
|
||||
|
||||
public final Project getProject() {
|
||||
return myProject;
|
||||
|
||||
+53
-31
@@ -344,30 +344,27 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
|
||||
Runnable action = new TaskContainer(task) {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean canceled = false;
|
||||
boolean processCanceled = false;
|
||||
Exception exception = null;
|
||||
try {
|
||||
ProgressManager.getInstance().runProcess(process, progressIndicator);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
canceled = true;
|
||||
processCanceled = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
if (canceled || progressIndicator.isCanceled()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
task.onCancel();
|
||||
}
|
||||
}, modalityState);
|
||||
}
|
||||
else {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
task.onSuccess();
|
||||
}
|
||||
}, modalityState);
|
||||
}
|
||||
final boolean finalCanceled = processCanceled || progressIndicator.isCanceled();
|
||||
final Exception finalException = exception;
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finishTask(task, finalCanceled, finalException);
|
||||
}
|
||||
}, modalityState);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -375,22 +372,47 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
|
||||
}
|
||||
|
||||
protected boolean runProcessWithProgressSynchronously(@NotNull final Task task, @Nullable final JComponent parentComponent) {
|
||||
final boolean result = ((ApplicationEx)ApplicationManager.getApplication())
|
||||
.runProcessWithProgressSynchronously(new TaskContainer(task) {
|
||||
@Override
|
||||
public void run() {
|
||||
new TaskRunnable(task, ProgressManager.getInstance().getProgressIndicator()).run();
|
||||
}
|
||||
}, task.getTitle(), task.isCancellable(), task.getProject(), parentComponent, task.getCancelText());
|
||||
if (result) {
|
||||
task.onSuccess();
|
||||
}
|
||||
else {
|
||||
task.onCancel();
|
||||
}
|
||||
final Ref<Exception> exceptionRef = new Ref<Exception>();
|
||||
TaskContainer taskContainer = new TaskContainer(task) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
new TaskRunnable(task, ProgressManager.getInstance().getProgressIndicator()).run();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication();
|
||||
boolean result = application.runProcessWithProgressSynchronously(taskContainer, task.getTitle(), task.isCancellable(),
|
||||
task.getProject(), parentComponent, task.getCancelText());
|
||||
|
||||
finishTask(task, !result, exceptionRef.get());
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static void finishTask(@NotNull Task task, boolean canceled, @Nullable Exception exception) {
|
||||
try {
|
||||
if (exception != null) {
|
||||
task.onError(exception);
|
||||
}
|
||||
else if (canceled) {
|
||||
task.onCancel();
|
||||
}
|
||||
else {
|
||||
task.onSuccess();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
task.onFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator progressIndicator) {
|
||||
runProcessWithProgressAsynchronously(task, progressIndicator, null);
|
||||
|
||||
+1
-2
@@ -136,13 +136,12 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
onFinished();
|
||||
myPopup.setCaption(getCaption(getCurrentSize()));
|
||||
paintBusy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinished() {
|
||||
public void onFinished() {
|
||||
myFinished = true;
|
||||
}
|
||||
|
||||
|
||||
+13
-7
@@ -120,21 +120,26 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
|
||||
TaskContainer action = new TaskContainer(task) {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean canceled = false;
|
||||
boolean processCanceled = false;
|
||||
Exception exception = null;
|
||||
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
ProgressManager.getInstance().runProcess(process, progressIndicator);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
canceled = true;
|
||||
processCanceled = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
final long end = System.currentTimeMillis();
|
||||
final long time = end - start;
|
||||
|
||||
if (canceled || progressIndicator.isCanceled()) {
|
||||
ApplicationManager.getApplication().invokeLater(() -> task.onCancel(), modalityState);
|
||||
}
|
||||
else {
|
||||
final boolean finalCanceled = processCanceled || progressIndicator.isCanceled();
|
||||
final Exception finalException = exception;
|
||||
|
||||
if (!finalCanceled) {
|
||||
final Task.NotificationInfo notificationInfo = task.notifyFinished();
|
||||
if (notificationInfo != null && time > 5000) { // snow notification if process took more than 5 secs
|
||||
final Component window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
||||
@@ -142,8 +147,9 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
|
||||
systemNotify(notificationInfo);
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater(() -> task.onSuccess(), modalityState);
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(() -> finishTask(task, finalCanceled, finalException), modalityState);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user