Bug 299731 [Progress] ProgressMonitorDialog should check for widget state in its async runnable
setOperationCancelButtonEnabled(boolean) should check whether the widget has been disposed or not before invoking setEnabled(boolean). Since this method is called in an asynchronous runnable, there is no guarantee that the widgets are still up when the display gets around to processing them. Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new GridLayout(1, false)); shell.pack(); shell.open(); ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell); pmd.open(); pmd.run(false, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { } }); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); Exception in thread "main" org.eclipse.swt.SWTException: Failed to execute runnable (org.eclipse.swt.SWTException: Widget is disposed) at org.eclipse.swt.SWT.error(SWT.java:4068) at org.eclipse.swt.SWT.error(SWT.java:3983) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:137) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3906) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3527) at org.eclipse.ui.Test.main(Test.java:45) Caused by: org.eclipse.swt.SWTException: Widget is disposed at org.eclipse.swt.SWT.error(SWT.java:4068) at org.eclipse.swt.SWT.error(SWT.java:3983) at org.eclipse.swt.SWT.error(SWT.java:3954) at org.eclipse.swt.widgets.Widget.error(Widget.java:467) at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:340) at org.eclipse.swt.widgets.Control.setEnabled(Control.java:2928) at org.eclipse.jface.dialogs.ProgressMonitorDialog.setOperationCancelButtonEnabled(ProgressMonitorDialog.java:622) at org.eclipse.jface.dialogs.ProgressMonitorDialog$1.run(ProgressMonitorDialog.java:329) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134) ... 3 more
bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/ProgressMonitorDialog.java
/**
	 * Sets whether the dialog should be opened before the operation is run.
	 * NOTE: Setting this to false and not forking a process may starve any
	 * asyncExec that tries to open the dialog later.
	 * 
	 * @param openOnRun
	 *            <code>true</code> to open the dialog before run,
	 *            <code>false</code> to only create the dialog, but not open
	 *            it
	 * @since 3.0
	 */
	public void setOpenOnRun(boolean openOnRun) {
		this.openOnRun = openOnRun;
	}
	/**
	 * Returns the nesting depth of running operations.
	 * 
	 * @return the nesting depth of running operations
	 * @since 3.0
	 */
	protected int getNestingDepth() {
		return nestingDepth;
	}
	/**
	 * Increments the nesting depth of running operations.
	 * 
	 * @since 3.0
	 */
	protected void incrementNestingDepth() {
		nestingDepth++;