### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.forms Index: src/org/eclipse/ui/forms/widgets/Section.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Section.java,v retrieving revision 1.43 diff -u -r1.43 Section.java --- src/org/eclipse/ui/forms/widgets/Section.java 16 Mar 2007 20:24:01 -0000 1.43 +++ src/org/eclipse/ui/forms/widgets/Section.java 5 Sep 2007 18:39:23 -0000 @@ -27,6 +27,7 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.internal.forms.widgets.FormImages; import org.eclipse.ui.internal.forms.widgets.FormUtil; /** @@ -89,8 +90,9 @@ Listener listener = new Listener() { public void handleEvent(Event e) { Image image = Section.super.getBackgroundImage(); - if (image != null) - image.dispose(); + if (image != null) { + FormImages.markFinished(image); + } Section.super.setBackgroundImage(null); } }; @@ -457,15 +459,7 @@ private void updateHeaderImage(Color bg, Rectangle bounds, int theight, int realtheight) { - Image image = new Image(getDisplay(), 1, realtheight); - image.setBackground(getBackground()); - GC gc = new GC(image); - gc.setBackground(getBackground()); - gc.fillRectangle(0, 0, 1, realtheight); - gc.setForeground(bg); - gc.setBackground(getBackground()); - gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true); - gc.dispose(); + Image image = FormImages.getGradient(getDisplay(), getBackground(), bg, realtheight, theight, marginHeight); super.setBackgroundImage(image); } Index: src/org/eclipse/ui/internal/forms/widgets/FormImages.java =================================================================== RCS file: src/org/eclipse/ui/internal/forms/widgets/FormImages.java diff -N src/org/eclipse/ui/internal/forms/widgets/FormImages.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/forms/widgets/FormImages.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.forms.widgets; + +import java.util.HashMap; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class FormImages { + private static HashMap images; + private static HashMap ids; + + private static class ImageIdentifier { + private Display fDisplay; + private Color fColor1; + private Color fColor2; + private int fRealtheight; + private int fTheight; + private int fMarginHeight; + + ImageIdentifier (Display display, Color color1, Color color2, + int realtheight, int theight, int marginHeight) { + fDisplay = display; + fColor1 = color1; + fColor2 = color2; + fRealtheight = realtheight; + fTheight = theight; + fMarginHeight = marginHeight; + } + + public boolean equals(Object obj) { + if (obj instanceof ImageIdentifier) { + ImageIdentifier id = (ImageIdentifier) obj; + if (id.fDisplay.equals(fDisplay) && id.fColor1.equals(fColor1) && + id.fColor2.equals(fColor2) && id.fRealtheight == fRealtheight && + id.fTheight == fTheight && id.fMarginHeight == fMarginHeight) + return true; + } + return false; + } + + public int hashCode() { + int hash = fDisplay.hashCode(); + hash = hash * 7 + fColor1.hashCode(); + hash = hash * 7 + fColor2.hashCode(); + hash = hash * 7 + new Integer(fRealtheight).hashCode(); + hash = hash * 7 + new Integer(fTheight).hashCode(); + hash = hash * 7 + new Integer(fMarginHeight).hashCode(); + return hash; + } + } + + private static class ImageReference { + private Image fImage; + private int fCount; + + public ImageReference(Image image) { + fImage = image; + fCount = 1; + } + + public Image getImage() { + return fImage; + } + // returns a boolean indicating if all clients of this image are finished + // a true result indicates the underlying image should be disposed + public boolean decCount() { + return --fCount == 0; + } + public void incCount() { + fCount++; + } + } + + public static Image getGradient(Display display, Color color1, Color color2, + int realtheight, int theight, int marginHeight) { + checkHashMaps(); + ImageIdentifier id = new ImageIdentifier(display, color1, color2, realtheight, theight, marginHeight); + ImageReference result = (ImageReference) images.get(id); + if (result != null && !result.getImage().isDisposed()) { + result.incCount(); + return result.getImage(); + } + Image image = createGradient(display, color1, color2, realtheight, theight, marginHeight); + images.put(id, new ImageReference(image)); + ids.put(image, id); + return image; + } + + public static boolean markFinished(Image image) { + checkHashMaps(); + ImageIdentifier id = (ImageIdentifier)ids.get(image); + if (id != null) { + ImageReference ref = (ImageReference) images.get(id); + if (ref != null) { + if (ref.decCount()) { + images.remove(id); + ids.remove(ref.getImage()); + ref.getImage().dispose(); + validateHashMaps(); + } + return true; + } + } + return false; + } + + private static void validateHashMaps() { + if (images.size() == 0) + images = null; + if (ids.size() == 0) + ids = null; + } + + private static void checkHashMaps() { + if (images == null) + images = new HashMap(); + if (ids == null) + ids = new HashMap(); + } + + private static Image createGradient(Display display, Color color1, Color color2, + int realtheight, int theight, int marginHeight) { + Image image = new Image(display, 1, realtheight); + image.setBackground(color1); + GC gc = new GC(image); + gc.setBackground(color1); + gc.fillRectangle(0, 0, 1, realtheight); + gc.setForeground(color2); + gc.setBackground(color1); + gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true); + gc.dispose(); + return image; + } +}