Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 349805

Summary: [FORMS] FormToolkit#setBackground disposes Colors which are still in use
Product: [Eclipse Project] Platform Reporter: Remo Loetscher <remo.loetscher>
Component: User AssistanceAssignee: Chris Goldthorpe <cgold>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: cgold, pwebster, remo.loetscher, remy.suen
Version: 3.6.2   
Target Milestone: ---   
Hardware: PC   
OS: Windows Vista   
Whiteboard: stalebug
Attachments:
Description Flags
Force the dispose color bug
none
Force the dispose color bug (Workaround)
none
Force the dispose color bug (Workaround) none

Description Remo Loetscher CLA 2011-06-20 07:24:03 EDT
Build Identifier: Helios Service Release 2 - Build id: 20110218-0911

Occured on Version org.eclipse.ui.forms_3.5.2.r36_v20100702:

If on a FormToolkit is the setBackground Method called it disposes colors which are still in use. A repaint of the Form will result in the following Stacktrace:

java.lang.IllegalArgumentException: Argument not valid
	at org.eclipse.swt.SWT.error(SWT.java:4064)
	at org.eclipse.swt.SWT.error(SWT.java:3998)
	at org.eclipse.swt.SWT.error(SWT.java:3969)
	at org.eclipse.swt.graphics.GC.setForeground(GC.java:4427)
	at org.eclipse.ui.forms.widgets.Section.onPaint(Section.java:416)
	at org.eclipse.ui.forms.widgets.ExpandableComposite$1.paintControl(ExpandableComposite.java:555)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:223)
	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:1062)
	at org.eclipse.swt.widgets.Composite.WM_PAINT(Composite.java:1555)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:4218)
	at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4886)
	at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2459)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3655)

The background for the FormHeader (and Sections) is erased.

Reproducible: Always

Steps to Reproduce:
1. Run the Snippet "FormColorDisposeBug.java" on a windows vista machine (32 bit)
2. Press the button "FormToolkit#setBackground(Color)"
3. Resize the Shell
4. The background color for the FormHeader and Section is "invisible"
Comment 1 Remo Loetscher CLA 2011-06-20 07:24:50 EDT
Created attachment 198249 [details]
Force the dispose color bug
Comment 2 Remo Loetscher CLA 2011-06-23 06:54:45 EDT
Importance set new from "major" to "normal".
Workaround found:
If a formtoolkit with an own FormColor is used the background can be set/changed on that toolkit.
See attached file "Force the dispose color bug (Workaround)" -> Button "FormToolkit(with own FormColors)#setBackground(Color)".
Comment 3 Remo Loetscher CLA 2011-06-23 06:55:17 EDT
Created attachment 198459 [details]
Force the dispose color bug (Workaround)
Comment 4 Chris Goldthorpe CLA 2011-06-23 17:53:11 EDT
I was able to reproduce the bug, I will look into it.
Comment 5 Remo Loetscher CLA 2011-06-24 05:27:36 EDT
The bug occurs only if on the same FormToolkit is used for header decoration AND background change:

Snippet 1 - this will fail:
FormToolkit toolkit_default = new FormToolkit(shell.getDisplay());
toolkit_default.decorateFormHeading(<form>);
toolkit_default.setBackground(<color>);
toolkit_default.createXYZ();

Snippet 2 - this will work:
FormToolkit toolkit_default = new FormToolkit(shell.getDisplay());
FormToolkit tollkit_with_new_background = new FormToolkit(shell.getDisplay());
toolkit_default.decorateFormHeading(<form>);
tollkit_with_new_background.setBackground(<color>);
tollkit_with_new_background.createXYZ();

Note that in the second snippet the decoration is not done by the toolkit on which the background color was changed.
btw: Using a new FormColor object seems to have no effect on that...

The "reason" for this bug is in the FormToolkit#decorateFormHeading() which will "force" the FormColor by calling FormColor#getColor() to run initializeFormHeaderColors() and initializeSectionToolBarColors().
If the FormColor is "initialized" in that way a call FormColor#setBackground() will dispose the colors in the FormColor#updateFormHeaderColors() Method.
In Snippet 2 the FormColor is not yet initialized, so the method FormColor#updateFormHeaderColors() does nothing.
If no FormToolkit#decorateFormHeading() method is called in any way, there is no problem.

I adapted the snippet which is attached to this bug.
Comment 6 Remo Loetscher CLA 2011-06-24 05:28:45 EDT
Created attachment 198509 [details]
Force the dispose color bug (Workaround)
Comment 7 Chris Goldthorpe CLA 2011-06-27 13:40:39 EDT
This is what I think is happening. Each FormToolkit has a FormColors object which is used to store the colors used in a form, these colors are created and owned by the FormColors object and are derived from the foreground and background colors using blending rules. If the foreground or background color changes new colors are created and the old ones disposed. What should instead happen is that the colors are not disposed until the FormToolit is disposed. My only concern with deferring the disposal would be that a program which contained a FormToolkit object with a long lifetime would consume more memory every time a call to setBackround() is made.

It sounds as though you have a workaround and this bug is not blocking you - is that correct?
Comment 8 Remo Loetscher CLA 2011-06-28 01:51:18 EDT
(In reply to comment #7)

> It sounds as though you have a workaround and this bug is not blocking you - is
that correct?

Yes, the bug is not blocking anymore. The attached workaround works for me.
But nevertheless the "undocumented dependency" between the function call "FormToolkit#decorateFormHeading()" and "FormToolkit#setBackground()" should be fixed/documented in a way.
The problem occurs only if decorateFormHeading() and setBackground is called in that order on the same toolkit instance.

So possible fixes could be:
- do not dispose colors if the form header was decorated and setBackground is called -> use the "old" colors -> setting background has no impact in the blending rules for headers and sections
- allow to set/change background color only at a specific point -> before the first decorateFormHeading() call; this way setting the background works
- Document the "dependency" in the javadoc
[- resetting references to colors in sections and form header after setBackground() was called]
Comment 9 Eclipse Genie CLA 2019-10-01 18:39:56 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.