| Summary: | [Wizards] Widget is disposed exception when closing the wizard | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | BensonN <benson.ning> |
| Component: | UI | Assignee: | Platform UI Triaged <platform-ui-triaged> |
| Status: | CLOSED DUPLICATE | QA Contact: | Prakash Rangaraj <prakash> |
| Severity: | major | ||
| Priority: | P3 | CC: | bokowski, daniel_megert, eclipse.felipe, grant_gayed, lshanmug, pwebster, remy.suen, rtaniwa |
| Version: | 3.6 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
Here is the exception stack: !STACK 0 org.eclipse.swt.SWTException: Widget is disposed at org.eclipse.swt.SWT.error(SWT.java:4083) at org.eclipse.swt.SWT.error(SWT.java:3998) at org.eclipse.swt.SWT.error(SWT.java:3969) 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.Composite.computeSize(Composite.java:226) at org.eclipse.swt.custom.ScrolledCompositeLayout.computeSize(ScrolledCompositeLayout.java:32) at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233) at org.eclipse.jface.wizard.WizardDialog$PageContainerFillLayout.computeSize(WizardDialog.java:233) at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233) at org.eclipse.swt.layout.GridData.computeSize(GridData.java:483) at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217) at org.eclipse.swt.layout.GridLayout.computeSize(GridLayout.java:162) at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233) at org.eclipse.swt.layout.GridData.computeSize(GridData.java:483) at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217) at org.eclipse.swt.layout.GridLayout.computeSize(GridLayout.java:162) at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233) at org.eclipse.swt.layout.FormData.computeSize(FormData.java:117) at org.eclipse.swt.layout.FormData.getWidth(FormData.java:146) at org.eclipse.swt.layout.FormLayout.computeWidth(FormLayout.java:277) at org.eclipse.swt.layout.FormLayout.layout(FormLayout.java:332) at org.eclipse.swt.layout.FormLayout.computeSize(FormLayout.java:241) at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233) at org.eclipse.swt.layout.GridData.computeSize(GridData.java:483) at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217) at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:193) at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1275) at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1261) at org.eclipse.swt.widgets.Composite.layout(Composite.java:664) at org.eclipse.swt.widgets.Composite.layout(Composite.java:622) at org.eclipse.swt.widgets.Composite.layout(Composite.java:585) at org.eclipse.jface.dialogs.TitleAreaDialog.layoutForNewMessage(TitleAreaDialog.java:473) at org.eclipse.jface.dialogs.TitleAreaDialog.access$0(TitleAreaDialog.java:427) at org.eclipse.jface.dialogs.TitleAreaDialog$1.handleEvent(TitleAreaDialog.java:166) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1076) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1057) at org.eclipse.swt.widgets.Control.sendResize(Control.java:2648) at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:975) at org.eclipse.swt.widgets.Composite.setBounds(Composite.java:1024) at org.eclipse.swt.widgets.Decorations.setBounds(Decorations.java:871) at org.eclipse.swt.widgets.Shell.setBounds(Shell.java:1476) at org.eclipse.swt.widgets.Control.setBounds(Control.java:2776) at org.eclipse.swt.widgets.Control.setBounds(Control.java:2772) at org.eclipse.jface.dialogs.TrayDialog.closeTray(TrayDialog.java:165) at org.eclipse.jface.dialogs.TrayDialog.close(TrayDialog.java:177) at org.eclipse.jface.wizard.WizardDialog.hardClose(WizardDialog.java:871) at org.eclipse.jface.wizard.WizardDialog.finishPressed(WizardDialog.java:819) at org.eclipse.jface.wizard.WizardDialog.buttonPressed(WizardDialog.java:430) at org.eclipse.jface.dialogs.Dialog$2.widgetSelected(Dialog.java:624) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657) at org.eclipse.jface.window.Window.runEventLoop(Window.java:825) at org.eclipse.jface.window.Window.open(Window.java:801) at org.eclipse.ui.internal.handlers.WizardHandler$New.executeHandler(WizardHandler.java:254) at org.eclipse.ui.internal.handlers.WizardHandler.execute(WizardHandler.java:274) at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293) at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476) at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508) at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169) at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241) at org.eclipse.ui.internal.actions.CommandAction.runWithEvent(CommandAction.java:157) at org.eclipse.ui.internal.actions.CommandAction.run(CommandAction.java:171) at org.eclipse.ui.actions.NewWizardDropDownAction.run(NewWizardDropDownAction.java:182) at org.eclipse.jface.action.Action.runWithEvent(Action.java:498) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501) at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427) at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:600) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574) at org.eclipse.equinox.launcher.Main.run(Main.java:1407) at org.eclipse.equinox.launcher.Main.main(Main.java:1383) Hi, Can someone please take a look on this problem? looks like it's a regression, didn't see the problem from the old eclipse. Thanks for your time. Lakshmi can you investigate which 3.6 change(s) made this stop working? You can use eclipse's Plug-in Project creation wizard to create an example wizard and then substitute in the comment 0 code. It's not initially clear whether this is a problem in swt or jface. Thanks! Actually wait a sec', the code in comment 0 includes: public void dispose() { container_.dispose(); super.dispose(); } I believe this is wrong, the javadoc for IDialogPage.dispose() says "Disposes the SWT resources allocated by this dialog page.". Unfortunately the phrase "SWT resources allocated" is a bit ambiguous, but I believe it's referring to graphics resources that need to be explicitly disposed (Images, Fonts, etc.), NOT to widget resources which container_.dispose() would do. I can make the comment 0 code work by getting rid of its dispose() method, and I believe this is actually correct. Paul can you confirm that this is the intent of a WizardPage's dispose() implementation, to provide an opportunity for a page to dispose of its allocated _graphics_ resources only? The code there is just a sub-set code of our logic, we have some logic needs to dispose the composite there, it worked before and also works for finishing the wizard without opening the help section. even with help section opened, it worked on old eclipse as well, is there anything new introduced in 3.6? Thanks for looking at this. In 3.6, There were some changes in the message layout in the TitleAreaDialog. So you might not get any exceptions earlier. But as Grant says in Comment #4, you shouldn't be disposing the composite in the page.dispose(). It should be automatically disposed when the wizard's control is disposed. You shouldn't be doing it. The problem is that in the code in comment #0 the container_ is disposed but it is still the content of the ScrolledComposite. So, exception occurs in ScrolledCompositeLayout.computeSize(). If the code is disposing of the control (container_) which is set as the content of the ScrolledComposite it could set scroller.setContent(null). Since our page is a dynamic layout page, it bases on the user selection to generate/remove the UI control area, unfortunately, when the wizard is being closed, the page removes the UI control area, just like the container_.dispose() call from my example code. I am not sure why it's a wrong behavior and don't know why I can NOT do it. The exception happens only when the help section is opened, and seems like ScrolledCompositeLayout only computes the size when the help is shown, if that's the case, can a safe check be added to the "ScrolledCompositeLayout.computeSize()"?, don't know why the layout needs to recompute the size when the page with help section is being disposed. Thanks Sorry Benson, your code is wrong. Closing this bug as NOT_ECLISPE.
You can not dispose container_ while it is still be referenced by scroller.
You can:
a) remove TestWizard_PGChanged_Page#dispose()
You don't need to explicitly dispose container_ as it will be disposed along with the parent.
b) change TestWizard_PGChanged_Page#dispose() as follow
public void dispose()
{
ScrolledComposite scroller = (ScrolledComposite) container_.getParent();
scroller.setContent(null);
container_.dispose();
super.dispose();
}
or
public void dispose()
{
super.dispose();
container_.dispose();//pointless, container_ should already be disposed at this point...
}
Thanks for looking at the problem. Do you have any detailed JavaDoc or guide line for this API? since it's a public API, I really prefer to have something to tell me what's the correct thing I can do there, it will really help to prevent the thing (especially the one that works ok today, but may not in the future) to happen again. Thanks again. The closest one is this: http://www.eclipse.org/articles/swt-design-2/swt-design-2.html It should help you to understand when and how to dispose widgets and resources. Thanks, I will take a look and hopefully it helps.
By the way, I tried the workaround #2:
public void dispose()
{
super.dispose();
container_.dispose();//pointless, container_ should already be disposed
at this point...
}
It doesn't help, I still can get the exception, so the super.dispose() didn't dispose the container_? looks like I can not dispose the content anytime and anywhere?
Where is the stack trace ? Didn't is crash on super.dispose() or container_.dispose(). Note: I didn't read the entire code, I believe that somewhere in the UI code there is a hook for Dispose events that is running some code that your (indirectly) touching your disposed container_ . Why do you need to dispose container_ ? Can you let it be disposed along with the parent when the entire hierarchy is disposed ? Please look at comment #1 for the stack trace. The reason is: (comment 8 for details and questions): "Since our page is a dynamic layout page, it bases on the user selection to generate/remove the UI control area, unfortunately, when the wizard is being closed, the page removes the UI control area, just like the container_.dispose() call from my example code. " Our code is kind of old, has not been changed for a while, it worked before, but got the exception on the latest 3.6.0 eclipse. I am sorry, I have to reopen it, I changed the code little bit and I got a different exception but also from ScrolledCompositeLayout.computeSize(...). This time, I added an image to a label and set the label to be the content of the composite, in the dispose method, I disposed the image.
This is the new code:
@Override
public void createControl(Composite parent)
{
scroller_ = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
scroller_.setExpandHorizontal(true);
scroller_.setExpandVertical(true);
scroller_.setLayout(new GridLayout());
scroller_.setLayoutData(new GridData(GridData.FILL_BOTH));
Label label = new Label(scroller_, SWT.NONE);
img_ = TestPlugin.getImageDescriptor("icons/connection.gif").createImage();
label.setImage(img_);
scroller_.setContent(label);
this.setPageComplete(true);
setControl(scroller_);
}
@Override
public void dispose()
{
super.dispose();
img_.dispose();
}
Exception:
!STACK 0
org.eclipse.swt.SWTException: Graphic is disposed
at org.eclipse.swt.SWT.error(SWT.java:4083)
at org.eclipse.swt.SWT.error(SWT.java:3998)
at org.eclipse.swt.SWT.error(SWT.java:3969)
at org.eclipse.swt.graphics.Image.getBounds(Image.java:1164)
at org.eclipse.swt.widgets.Label.computeSize(Label.java:150)
at org.eclipse.swt.custom.ScrolledCompositeLayout.computeSize(ScrolledCompositeLayout.java:32)
at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233)
at org.eclipse.jface.wizard.WizardDialog$PageContainerFillLayout.computeSize(WizardDialog.java:233)
at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233)
at org.eclipse.swt.layout.GridData.computeSize(GridData.java:491)
at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217)
at org.eclipse.swt.layout.GridLayout.computeSize(GridLayout.java:162)
at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233)
at org.eclipse.swt.layout.GridData.computeSize(GridData.java:491)
at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217)
at org.eclipse.swt.layout.GridLayout.computeSize(GridLayout.java:162)
at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233)
at org.eclipse.swt.layout.FormData.computeSize(FormData.java:117)
at org.eclipse.swt.layout.FormData.getWidth(FormData.java:146)
at org.eclipse.swt.layout.FormLayout.computeWidth(FormLayout.java:277)
at org.eclipse.swt.layout.FormLayout.layout(FormLayout.java:332)
at org.eclipse.swt.layout.FormLayout.computeSize(FormLayout.java:241)
at org.eclipse.swt.widgets.Composite.computeSize(Composite.java:233)
at org.eclipse.swt.layout.GridData.computeSize(GridData.java:491)
at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:217)
at org.eclipse.swt.layout.GridLayout.layout(GridLayout.java:193)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1275)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1261)
at org.eclipse.swt.widgets.Composite.layout(Composite.java:664)
at org.eclipse.swt.widgets.Composite.layout(Composite.java:622)
at org.eclipse.swt.widgets.Composite.layout(Composite.java:585)
at org.eclipse.jface.dialogs.TitleAreaDialog.layoutForNewMessage(TitleAreaDialog.java:473)
at org.eclipse.jface.dialogs.TitleAreaDialog.access$0(TitleAreaDialog.java:427)
at org.eclipse.jface.dialogs.TitleAreaDialog$1.handleEvent(TitleAreaDialog.java:166)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1058)
at org.eclipse.swt.widgets.Control.sendResize(Control.java:2649)
at org.eclipse.swt.widgets.Composite.sendResize(Composite.java:975)
at org.eclipse.swt.widgets.Composite.setBounds(Composite.java:1024)
at org.eclipse.swt.widgets.Decorations.setBounds(Decorations.java:871)
at org.eclipse.swt.widgets.Shell.setBounds(Shell.java:1476)
at org.eclipse.swt.widgets.Control.setBounds(Control.java:2777)
at org.eclipse.swt.widgets.Control.setBounds(Control.java:2773)
at org.eclipse.jface.dialogs.TrayDialog.closeTray(TrayDialog.java:165)
at org.eclipse.jface.dialogs.TrayDialog.close(TrayDialog.java:177)
at org.eclipse.jface.wizard.WizardDialog.hardClose(WizardDialog.java:871)
at org.eclipse.jface.wizard.WizardDialog.close(WizardDialog.java:484)
at org.eclipse.jface.wizard.WizardDialog.cancelPressed(WizardDialog.java:471)
at org.eclipse.jface.wizard.WizardDialog$1.widgetSelected(WizardDialog.java:321)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:825)
at org.eclipse.jface.window.Window.open(Window.java:801)
at org.eclipse.ui.internal.handlers.WizardHandler$New.executeHandler(WizardHandler.java:254)
at org.eclipse.ui.internal.handlers.WizardHandler.execute(WizardHandler.java:274)
at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241)
at org.eclipse.ui.internal.actions.CommandAction.runWithEvent(CommandAction.java:157)
at org.eclipse.ui.internal.actions.CommandAction.run(CommandAction.java:171)
at org.eclipse.ui.actions.NewWizardDropDownAction.run(NewWizardDropDownAction.java:182)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
I just looked into super.dispose(). It doesn't dispose the controls in the page. In your example, the problem is on the same lines as mentioned in comment #7. public void dispose() { super.dispose(); img_.dispose(); } super.dispose() doesn't dispose the scroller or the label. At this point the label is not yet disposed, but you are disposing the image that is set to the label. A call to Label.computeSize() now causes exception because the image is set to the label, but the image is already disposed. The fix can be : super.dispose() scroller.dispose() //disposes the child label too img_.dispose() However, I'm not sure why the layout is being computed when the wizard is just about to be closed. Is it expected? Moving to Platform UI for comments. That's my question as well (please see comment #8), seems like it is something new on the recent Eclipse, we didn't have the problem on the old version. As I mentioned in Comment #6, TitleAreaDialog has some changes. It now listens for resize events, so that it can calculate whether the entire title message can be shown or not. Although this is a new behaviour in 3.6, I don't think its a regression. I'm adding Boris for comments. Additionally, I don't think its valid to dispose of the content of a ScrolledComposite without disposing the ScrolledComposite itself is valid. You should either set an empty content or dispose off the ScrolledComposite instead of its content. (In reply to comment #15) > I am sorry, I have to reopen it, I changed the code little bit and I got a > different exception but also from ScrolledCompositeLayout.computeSize(...). > This time, I added an image to a label and set the label to be the content of > the composite, in the dispose method, I disposed the image. > > Label label = new Label(scroller_, SWT.NONE); > img_ = > TestPlugin.getImageDescriptor("icons/connection.gif").createImage(); > label.setImage(img_); > > @Override > public void dispose() > { > super.dispose(); > img_.dispose(); > } If you dispose the image before the label is disposed, you are going to run into these kinds of problems. You should set the label's image to null and then dispose the image. While we may be able to change code on our end to avoid the problems you are seeing, it would be much safer if you disposed your resources in a safe manner. For example, do not dispose a ScrolledComposite's content (that you've set using setContent) without also disposing the ScrolledComposite itself, or calling setContent(null). Or do not dispose a Label's image (that you've set using setImage) without also disposing the label, or calling setImage(null). There's a pattern here... Disposing controls is OK as long as their only relationship with each other is through calling constructors where you pass a parent composite. Whenever there is a setter you are calling (e.g. setContent, setImage), you cannot just dispose the content, or the image, because it may still be referenced. I hope this helps. *** This bug has been marked as a duplicate of bug 188651 *** |
Build Identifier: Eclipse 3.6.0 I have a wizard page like this: import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; public class TestWizard_PGChanged_Page extends WizardPage { protected Composite container_; public TestWizard_PGChanged_Page(String name) { super (name); setTitle("Test"); setDescription("Test"); } public void createControl(Composite parent) { ScrolledComposite scroller = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL); scroller.setExpandHorizontal(true); scroller.setExpandVertical(true); scroller.setLayout(new GridLayout()); scroller.setLayoutData(new GridData(GridData.FILL_BOTH)); container_ = new Composite(scroller, SWT.NULL); GridLayout layout = new GridLayout(); container_.setLayout(layout); container_.setLayoutData(new GridData(GridData.FILL_BOTH)); Label label = new Label(container_, SWT.NONE); label.setText("A label to be cleared"); scroller.setContent(container_); setControl(scroller); } public void dispose() { container_.dispose(); super.dispose(); } } Reproducible: Always Steps to Reproduce: 1. Bring up the wizard. 2. From the wizard page, press F1 to bring up the "help" section on the right. 3. Press "Finish" button to close the wizard. Got "Widget is disposed" exception.