View | Details | Raw Unified | Return to bug 200690 | Differences between
and this patch

Collapse All | Expand All

(-)forms/org/eclipse/ua/tests/forms/AllFormsTests.java (+2 lines)
Lines 15-20 Link Here
15
import junit.framework.TestSuite;
15
import junit.framework.TestSuite;
16
16
17
import org.eclipse.ua.tests.forms.layout.AllLayoutTests;
17
import org.eclipse.ua.tests.forms.layout.AllLayoutTests;
18
import org.eclipse.ua.tests.forms.util.AllUtilityTests;
18
19
19
/*
20
/*
20
 * Tests all cheat sheet functionality (automated).
21
 * Tests all cheat sheet functionality (automated).
Lines 33-37 Link Here
33
	 */
34
	 */
34
	public AllFormsTests() {
35
	public AllFormsTests() {
35
		addTest(AllLayoutTests.suite());
36
		addTest(AllLayoutTests.suite());
37
		addTest(AllUtilityTests.suite());
36
	}
38
	}
37
}
39
}
(-)forms/org/eclipse/ua/tests/forms/util/FormImagesTests.java (+75 lines)
Added Link Here
1
package org.eclipse.ua.tests.forms.util;
2
3
import org.eclipse.swt.graphics.Color;
4
import org.eclipse.swt.graphics.Image;
5
import org.eclipse.swt.widgets.Display;
6
import org.eclipse.ui.internal.forms.widgets.FormImages;
7
8
import junit.framework.Assert;
9
import junit.framework.TestCase;
10
11
public class FormImagesTests extends TestCase {
12
	public void testSingleton() {
13
		Display display = Display.getCurrent();
14
		FormImages instance = FormImages.getInstance();
15
		// ensure the singleton is returning the same instance
16
		Assert.assertTrue("getInstance() returned a different FormImages instance", instance.equals(FormImages.getInstance()));
17
		Image gradient = instance.getGradient(display, new Color(display, 1, 1, 1), new Color(display, 7, 7, 7), 21, 21, 0);
18
		instance.markFinished(gradient);
19
		// ensure the singleton is returning the same instance after creating and disposing one gradient
20
		Assert.assertTrue("getInstance() returned a different FormImages instance after creation and disposal of one image", instance.equals(FormImages.getInstance()));
21
	}
22
	
23
	public void testDisposeOne() {
24
		Display display = Display.getCurrent();
25
		Image gradient = FormImages.getInstance().getGradient(display, new Color(display, 255, 255, 255), new Color(display, 0, 0, 0), 21, 21, 0);
26
		FormImages.getInstance().markFinished(gradient);
27
		// ensure that getting a single gradient and marking it as finished disposed it
28
		Assert.assertTrue("markFinished(...) did not dispose an image after a single getGradient()", gradient.isDisposed());
29
	}
30
	
31
	public void testMultipleInstances() {
32
		Display display = Display.getCurrent();
33
		Image gradient = FormImages.getInstance().getGradient(display, new Color(display, 200, 200, 200), new Color(display, 0, 0, 0), 30, 16, 3);
34
		int count;
35
		// ensure that the same image is returned for many calls with the same parameter
36
		for (count = 1; count < 20; count ++)
37
			Assert.assertEquals("getGradient(...) returned a different image for the same params on iteration "+count,
38
					gradient, FormImages.getInstance().getGradient(display, new Color(display, 200, 200, 200), new Color(display, 0, 0, 0), 30, 16, 3));
39
		for ( ;count > 0; count--) {
40
			FormImages.getInstance().markFinished(gradient);
41
			if (count != 1)
42
				// ensure that the gradient is not disposed early
43
				Assert.assertFalse("markFinished(...) disposed a shared image early on iteration "+count,gradient.isDisposed());
44
			else
45
				// ensure that the gradient is disposed on the last markFinished
46
				Assert.assertTrue("markFinished(...) did not dispose a shared image on the last call",gradient.isDisposed());
47
		}
48
	}
49
	
50
	public void testMultipleUniqueInstances() {
51
		Display display = Display.getCurrent();
52
		Image[] images = new Image[10];
53
		images[0] = FormImages.getInstance().getGradient(display, new Color(display, 1, 0, 0), new Color(display, 100, 100, 100), 25, 23, 1);
54
		images[1] = FormImages.getInstance().getGradient(display, new Color(display, 0, 1, 0), new Color(display, 100, 100, 100), 25, 23, 1);
55
		images[2] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 1), new Color(display, 100, 100, 100), 25, 23, 1);
56
		images[3] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 101, 100, 100), 25, 23, 1);
57
		images[4] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 100, 101, 100), 25, 23, 1);
58
		images[5] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 100, 100, 101), 25, 23, 1);
59
		images[6] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 100, 100, 100), 20, 23, 1);
60
		images[7] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 100, 100, 100), 25, 10, 1);
61
		images[8] = FormImages.getInstance().getGradient(display, new Color(display, 0, 0, 0), new Color(display, 100, 100, 100), 25, 23, 2);
62
		images[9] = FormImages.getInstance().getGradient(display, new Color(display, 1, 1, 1), new Color(display, 101, 101, 101), 20, 10, 2);
63
		// ensure none of the images are the same
64
		for (int i = 0; i < images.length - 1; i++) {
65
			for (int j = i+1; j < images.length; j++) {
66
				Assert.assertNotSame("getGradient(...) returned the same image for different parameters: i = " + i + "; j = " + j, images[i], images[j]);
67
			}
68
		}
69
		// ensure all of the images are disposed with one call to markFinished
70
		for (int i = 0; i < images.length; i++) {
71
			FormImages.getInstance().markFinished(images[i]);
72
			Assert.assertTrue("markFinished(...) did not dispose an image that was only requested once: i = " + i, images[i].isDisposed());
73
		}
74
	}
75
}
(-)forms/org/eclipse/ua/tests/forms/util/AllUtilityTests.java (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ua.tests.forms.util;
12
13
import junit.framework.Test;
14
import junit.framework.TestSuite;
15
16
/*
17
 * Tests forms performance (automated).
18
 */
19
public class AllUtilityTests extends TestSuite {
20
21
	/*
22
	 * Returns the entire test suite.
23
	 */
24
	public static Test suite() {
25
		return new AllUtilityTests();
26
	}
27
28
	/*
29
	 * Constructs a new performance test suite.
30
	 */
31
	public AllUtilityTests() {
32
		addTestSuite(FormImagesTests.class);
33
	}
34
}
(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 10-16 Link Here
10
 org.eclipse.ui.forms.events,
10
 org.eclipse.ui.forms.events,
11
 org.eclipse.ui.forms.widgets,
11
 org.eclipse.ui.forms.widgets,
12
 org.eclipse.ui.internal.forms;x-internal:=true,
12
 org.eclipse.ui.internal.forms;x-internal:=true,
13
 org.eclipse.ui.internal.forms.widgets;x-internal:=true
13
 org.eclipse.ui.internal.forms.widgets;x-friends:="org.eclipse.ua.tests"
14
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.1.0,4.0.0)",
14
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.1.0,4.0.0)",
15
 org.eclipse.jface;bundle-version="[3.2.0,4.0.0)",
15
 org.eclipse.jface;bundle-version="[3.2.0,4.0.0)",
16
 org.eclipse.ui;bundle-version="[3.2.0,4.0.0)";resolution:=optional
16
 org.eclipse.ui;bundle-version="[3.2.0,4.0.0)";resolution:=optional
(-)src/org/eclipse/ui/forms/widgets/Section.java (-11 / +5 lines)
Lines 27-32 Link Here
27
import org.eclipse.swt.widgets.Event;
27
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Listener;
28
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Text;
29
import org.eclipse.swt.widgets.Text;
30
import org.eclipse.ui.internal.forms.widgets.FormImages;
30
import org.eclipse.ui.internal.forms.widgets.FormUtil;
31
import org.eclipse.ui.internal.forms.widgets.FormUtil;
31
32
32
/**
33
/**
Lines 89-96 Link Here
89
			Listener listener = new Listener() {
90
			Listener listener = new Listener() {
90
				public void handleEvent(Event e) {
91
				public void handleEvent(Event e) {
91
					Image image = Section.super.getBackgroundImage();
92
					Image image = Section.super.getBackgroundImage();
92
					if (image != null)
93
					if (image != null) {
93
						image.dispose();
94
						FormImages.getInstance().markFinished(image);
95
					}
94
					Section.super.setBackgroundImage(null);
96
					Section.super.setBackgroundImage(null);
95
				}
97
				}
96
			};
98
			};
Lines 457-471 Link Here
457
459
458
	private void updateHeaderImage(Color bg, Rectangle bounds, int theight,
460
	private void updateHeaderImage(Color bg, Rectangle bounds, int theight,
459
			int realtheight) {
461
			int realtheight) {
460
		Image image = new Image(getDisplay(), 1, realtheight);
462
		Image image = FormImages.getInstance().getGradient(getDisplay(), getBackground(), bg, realtheight, theight, marginHeight);
461
		image.setBackground(getBackground());
462
		GC gc = new GC(image);
463
		gc.setBackground(getBackground());
464
		gc.fillRectangle(0, 0, 1, realtheight);
465
		gc.setForeground(bg);
466
		gc.setBackground(getBackground());
467
		gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true);
468
		gc.dispose();
469
		super.setBackgroundImage(image);
463
		super.setBackgroundImage(image);
470
	}
464
	}
471
465
(-)src/org/eclipse/ui/internal/forms/widgets/FormImages.java (+157 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.forms.widgets;
12
13
import java.util.HashMap;
14
15
import org.eclipse.swt.graphics.Color;
16
import org.eclipse.swt.graphics.GC;
17
import org.eclipse.swt.graphics.Image;
18
import org.eclipse.swt.widgets.Display;
19
20
public class FormImages {
21
	private static FormImages instance;
22
23
	public static FormImages getInstance() {
24
		if (instance == null)
25
			instance = new FormImages();
26
		return instance;
27
	}
28
29
	private HashMap images;
30
	private HashMap ids;
31
	
32
	private FormImages() {
33
	}
34
	
35
	private class ImageIdentifier {
36
		private Display fDisplay;
37
		private Color fColor1;
38
		private Color fColor2;
39
		private int fRealtheight;
40
		private int fTheight;
41
		private int fMarginHeight;
42
		
43
		ImageIdentifier (Display display, Color color1, Color color2,
44
				int realtheight, int theight, int marginHeight) {
45
			fDisplay = display;
46
			fColor1 = color1;
47
			fColor2 = color2;
48
			fRealtheight = realtheight;
49
			fTheight = theight;
50
			fMarginHeight = marginHeight;
51
		}
52
		
53
		public boolean equals(Object obj) {
54
			if (obj instanceof ImageIdentifier) {
55
				ImageIdentifier id = (ImageIdentifier) obj;
56
				if (id.fDisplay.equals(fDisplay) && id.fColor1.equals(fColor1) &&
57
						id.fColor2.equals(fColor2) && id.fRealtheight == fRealtheight &&
58
						id.fTheight == fTheight && id.fMarginHeight == fMarginHeight)
59
					return true;
60
			}
61
			return false;
62
		}
63
		
64
		public int hashCode() {
65
			int hash = fDisplay.hashCode();
66
			hash = hash * 7 + fColor1.hashCode();
67
			hash = hash * 7 + fColor2.hashCode();
68
			hash = hash * 7 + new Integer(fRealtheight).hashCode();
69
			hash = hash * 7 + new Integer(fTheight).hashCode();
70
			hash = hash * 7 + new Integer(fMarginHeight).hashCode();
71
			return hash;
72
		}
73
	}
74
	
75
	private class ImageReference {
76
		private Image fImage;
77
		private int fCount;
78
		
79
		public ImageReference(Image image) {
80
			fImage = image;
81
			fCount = 1;
82
		}
83
84
		public Image getImage() {
85
			return fImage;
86
		}
87
		// returns a boolean indicating if all clients of this image are finished
88
		// a true result indicates the underlying image should be disposed
89
		public boolean decCount() {
90
			return --fCount == 0;
91
		}
92
		public void incCount() {
93
			fCount++;
94
		}
95
	}
96
	
97
	public Image getGradient(Display display, Color color1, Color color2,
98
			int realtheight, int theight, int marginHeight) {
99
		checkHashMaps();
100
		ImageIdentifier id = new ImageIdentifier(display, color1, color2, realtheight, theight, marginHeight);
101
		ImageReference result = (ImageReference) images.get(id);
102
		if (result != null && !result.getImage().isDisposed()) {
103
			result.incCount();
104
			return result.getImage();
105
		}
106
		Image image = createGradient(display, color1, color2, realtheight, theight, marginHeight);
107
		images.put(id, new ImageReference(image));
108
		ids.put(image, id);
109
		return image;
110
	}
111
	
112
	public boolean markFinished(Image image) {
113
		checkHashMaps();
114
		ImageIdentifier id = (ImageIdentifier)ids.get(image);
115
		if (id != null) {
116
			ImageReference ref = (ImageReference) images.get(id);
117
			if (ref != null) {
118
				if (ref.decCount()) {
119
					images.remove(id);
120
					ids.remove(ref.getImage());
121
					ref.getImage().dispose();
122
					validateHashMaps();
123
				}
124
				return true;
125
			}
126
		}
127
		return false;
128
	}
129
130
	private void checkHashMaps() {
131
		if (images == null)
132
			images = new HashMap();
133
		if (ids == null)
134
			ids = new HashMap();
135
	}
136
	
137
	private void validateHashMaps() {
138
		if (images.size() == 0)
139
			images = null;
140
		if (ids.size() == 0)
141
			ids = null;
142
	}
143
	
144
	private Image createGradient(Display display, Color color1, Color color2,
145
			int realtheight, int theight, int marginHeight) {
146
		Image image = new Image(display, 1, realtheight);
147
		image.setBackground(color1);
148
		GC gc = new GC(image);
149
		gc.setBackground(color1);
150
		gc.fillRectangle(0, 0, 1, realtheight);
151
		gc.setForeground(color2);
152
		gc.setBackground(color1);
153
		gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true);
154
		gc.dispose();
155
		return image;
156
	}
157
}

Return to bug 200690