alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*******************************************************************************
 * Copyright (c) 2006, 2008 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.jface.viewers;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * OwnerDrawLabelProvider is an abstract implementation of a label provider that
 * handles custom draw.
 * 
 * <p>
 * <b>This class is intended to be subclassed by implementors.
 * </p>
 * 
 * @since 3.3
 * 
 */
public abstract class OwnerDrawLabelProvider extends CellLabelProvider {

	static class OwnerDrawListener implements Listener {
		Set enabledColumns = new HashSet();
		int enabledGlobally = 0;
		private ColumnViewer viewer;

		OwnerDrawListener(ColumnViewer viewer) {
			this.viewer = viewer;
		}

		public void handleEvent(Event event) {
			CellLabelProvider provider = viewer.getViewerColumn(event.index)
					.getLabelProvider();
			ViewerColumn column = viewer.getViewerColumn(event.index);
			if (enabledGlobally > 0 || enabledColumns.contains(column)) {
				if (provider instanceof OwnerDrawLabelProvider) {
					Object element = event.item.getData();
					OwnerDrawLabelProvider ownerDrawProvider = (OwnerDrawLabelProvider) provider;
					switch (event.type) {
					case SWT.MeasureItem:
						ownerDrawProvider.measure(event, element);
						break;
					case SWT.PaintItem:
						ownerDrawProvider.paint(event, element);
						break;
					case SWT.EraseItem:
						ownerDrawProvider.erase(event, element);
						break;
					}
				}
			}
		}
	}

	private static final String OWNER_DRAW_LABEL_PROVIDER_LISTENER = "owner_draw_label_provider_listener"; //$NON-NLS-1$

	/**
	 * Set up the owner draw callbacks for the viewer.
	 * 
	 * @param viewer
	 *            the viewer the owner draw is set up
	 * 
	 * @deprecated Since 3.4, the default implementation of
	 *             {@link CellLabelProvider#initialize(ColumnViewer, ViewerColumn)}
	 *             in this class will set up the necessary owner draw callbacks
	 *             automatically. Calls to this method can be removed.
	 */
	public static void setUpOwnerDraw(final ColumnViewer viewer) {
		getOrCreateOwnerDrawListener(viewer).enabledGlobally++;
	}

	/**
	 * @param viewer
	 * @param control
	 * @return
	 */
	private static OwnerDrawListener getOrCreateOwnerDrawListener(
			final ColumnViewer viewer) {
		Control control = viewer.getControl();
		OwnerDrawListener listener = (OwnerDrawListener) control
				.getData(OWNER_DRAW_LABEL_PROVIDER_LISTENER);
		if (listener == null) {
			listener = new OwnerDrawListener(viewer);
			control.setData(OWNER_DRAW_LABEL_PROVIDER_LISTENER, listener);
			control.addListener(SWT.MeasureItem, listener);
			control.addListener(SWT.EraseItem, listener);
			control.addListener(SWT.PaintItem, listener);
		}
		return listener;
	}

	/**
	 * Create a new instance of the receiver based on a column viewer.
	 * 
	 */
	public OwnerDrawLabelProvider() {

	}

	public void dispose(ColumnViewer viewer, ViewerColumn column) {
		if (!viewer.getControl().isDisposed()) {
			setOwnerDrawEnabled(viewer, column, false);
		}
		super.dispose(viewer, column);
	}

	/**
	 * This implementation of
	 * {@link CellLabelProvider#initialize(ColumnViewer, ViewerColumn)}
	 * delegates to {@link #initialize(ColumnViewer, ViewerColumn, boolean)}
	 * with a value of <code>true for enableOwnerDraw.
	 * Subclasses may override this method but should either call the super
	 * implementation or, alternatively,
	 * {@link #initialize(ColumnViewer, ViewerColumn, boolean)}.
	 */
	protected void initialize(ColumnViewer viewer, ViewerColumn column) {
		this.initialize(viewer, column, true);
	}

	/**
	 * May be called from subclasses that override
	 * {@link #initialize(ColumnViewer, ViewerColumn)} but want to customize
	 * whether owner draw will be enabled. This method calls
	 * <code>super.initialize(ColumnViewer, ViewerColumn), and then
	 * enables or disables owner draw by calling
	 * {@link #setOwnerDrawEnabled(ColumnViewer, ViewerColumn, boolean)}.
	 * 
	 * @param viewer
	 *            the viewer
	 * @param column
	 *            the column, or <code>null if a column is not
	 *            available.
	 * @param enableOwnerDraw
	 *            <code>true if owner draw should be enabled for the
	 *            given viewer and column, <code>false otherwise.
	 * 
	 * @since 3.4
	 */
	final protected void initialize(ColumnViewer viewer, ViewerColumn column,
			boolean enableOwnerDraw) {
		super.initialize(viewer, column);
		setOwnerDrawEnabled(viewer, column, enableOwnerDraw);
	}

	public void update(ViewerCell cell) {
		// Force a redraw
		Rectangle cellBounds = cell.getBounds();
		cell.getControl().redraw(cellBounds.x, cellBounds.y, cellBounds.width,
				cellBounds.height, true);

	}

	/**
	 * Handle the erase event. The default implementation colors the background
	 * of selected areas with {@link SWT#COLOR_LIST_SELECTION} and foregrounds
	 * with {@link SWT#COLOR_LIST_SELECTION_TEXT}. Note that this
	 * implementation causes non-native behavior on some platforms. Subclasses
	 * should override this method and <b>not call the super
	 * implementation.
	 * 
	 * @param event
	 *            the erase event
	 * @param element
	 *            the model object
	 * @see SWT#EraseItem
	 * @see SWT#COLOR_LIST_SELECTION
	 * @see SWT#COLOR_LIST_SELECTION_TEXT
	 */
	protected void erase(Event event, Object element) {

		Rectangle bounds = event.getBounds();
		if ((event.detail & SWT.SELECTED) != 0) {

			Color oldForeground = event.gc.getForeground();
			Color oldBackground = event.gc.getBackground();

			event.gc.setBackground(event.item.getDisplay().getSystemColor(
					SWT.COLOR_LIST_SELECTION));
			event.gc.setForeground(event.item.getDisplay().getSystemColor(
					SWT.COLOR_LIST_SELECTION_TEXT));
			event.gc.fillRectangle(bounds);
			/* restore the old GC colors */
			event.gc.setForeground(oldForeground);
			event.gc.setBackground(oldBackground);
			/* ensure that default selection is not drawn */
			event.detail &= ~SWT.SELECTED;

		}

	}

	/**
	 * Handle the measure event.
	 * 
	 * @param event
	 *            the measure event
	 * @param element
	 *            the model element
	 * @see SWT#MeasureItem
	 */
	protected abstract void measure(Event event, Object element);

	/**
	 * Handle the paint event.
	 * 
	 * @param event
	 *            the paint event
	 * @param element
	 *            the model element
	 * @see SWT#PaintItem
	 */
	protected abstract void paint(Event event, Object element);

	/**
	 * Enables or disables owner draw for the given viewer and column. This
	 * method will attach or remove a listener to the underlying control as
	 * necessary. This method is called from
	 * {@link #initialize(ColumnViewer, ViewerColumn)} and
	 * {@link #dispose(ColumnViewer, ViewerColumn)} but may be called from
	 * subclasses to enable or disable owner draw dynamically.
	 * 
	 * @param viewer
	 *            the viewer
	 * @param column
	 *            the column, or <code>null if a column is not
	 *            available
	 * @param enabled
	 *            <code>true if owner draw should be enabled,
	 *            <code>false otherwise
	 * 
	 * @since 3.4
	 */
	protected void setOwnerDrawEnabled(ColumnViewer viewer,
			ViewerColumn column, boolean enabled) {
		if (enabled) {
			OwnerDrawListener listener = getOrCreateOwnerDrawListener(viewer);
			if (column == null) {
				listener.enabledGlobally++;
			} else {
				listener.enabledColumns.add(column);
			}
		} else {
			OwnerDrawListener listener = (OwnerDrawListener) viewer
					.getControl().getData(OWNER_DRAW_LABEL_PROVIDER_LISTENER);
			if (listener != null) {
				if (column == null) {
					listener.enabledGlobally--;
				} else {
					listener.enabledColumns.remove(column);
				}
				if (listener.enabledColumns.isEmpty()
						&& listener.enabledGlobally <= 0) {
					viewer.getControl().removeListener(SWT.MeasureItem,
							listener);
					viewer.getControl().removeListener(SWT.EraseItem, listener);
					viewer.getControl().removeListener(SWT.PaintItem, listener);
					viewer.getControl().setData(
							OWNER_DRAW_LABEL_PROVIDER_LISTENER, null);
				}
			}
		}
	}

}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.