/******************************************************************************* * Copyright (c) 2012 Laurent CARON * 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: * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation *******************************************************************************/ package org.mihalis.opal.propertyTable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; /** * Instances of this class are property sheets * <p> * <dl> * <dt><b>Styles:</b></dt> * <dd>BORDER</dd> * <dt><b>Events:</b></dt> * <dd>PTPropertyChange</dd> * </dl> * </p> */ public class PropertyTable extends Composite { final static int VIEW_AS_FLAT_LIST = 0; final static int VIEW_AS_CATEGORIES = 1; boolean showButtons; boolean showDescription; boolean sorted; int styleOfView; final List<PTProperty> properties; private boolean hasBeenBuilt = false; private final List<PTPropertyChangeListener> changeListeners; private PTWidget widget; /** * Constructs a new instance of this class given its parent and a style * value describing its behavior and appearance. * <p> * The style value is either one of the style constants defined in class * <code>SWT</code> which is applicable to instances of this class, or must * be built by <em>bitwise OR</em>'ing together (that is, using the * <code>int</code> "|" operator) two or more of those <code>SWT</code> * style constants. The class description lists the style constants that are * applicable to the class. Style bits are also inherited from superclasses. * </p> * * @param parent a composite control which will be the parent of the new * instance (cannot be null) * @param style the style of control to construct * * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> * </ul> * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the * thread that created the parent</li> * </ul> * */ public PropertyTable(final Composite parent, final int style) { super(parent, style); setLayout(new FillLayout(SWT.VERTICAL)); showButtons = true; showDescription = true; sorted = true; styleOfView = VIEW_AS_CATEGORIES; properties = new ArrayList<PTProperty>(); changeListeners = new ArrayList<PTPropertyChangeListener>(); widget = PTWidgetFactory.build(this); addListener(SWT.Resize, new Listener() { @Override public void handleEvent(final Event event) { // Draw the widget on first displaying if (!hasBeenBuilt) { widget.build(); hasBeenBuilt = true; } } }); } /** * Add a change listener (event fired when the value of a property is * changed) * * @param listener */ public void addChangeListener(final PTPropertyChangeListener listener) { changeListeners.add(listener); } /** * Add a property in this widget * * @param property property to add * @return the property */ public PTProperty addProperty(final PTProperty property) { if (properties.contains(property)) { throw new IllegalArgumentException("A property called '" + property.getName() + "' has already been declared."); } properties.add(property); property.setParentTable(this); return property; } /** * Fire the event "a value of a property has changed" * * @param property property which value has changed */ public void firePTPropertyChangeListeners(final PTProperty property) { for (final PTPropertyChangeListener listener : changeListeners) { listener.propertyHasChanged(property); } } /** * @return the values stored in this object in a map. Keys are property's * name, values are values stored in a the property. */ public Map<String, Object> getProperties() { final Map<String, Object> map = new HashMap<String, Object>(); for (final PTProperty prop : properties) { map.put(prop.getName(), prop.getValue()); } return map; } /** * @return the properties stored in a list */ public List<PTProperty> getPropertiesAsList() { return new ArrayList<PTProperty>(properties); } /** * Hide all buttons * * @return this property table */ public PropertyTable hideButtons() { showButtons = false; return rebuild(); } /** * Hide description * * @return this property table */ public PropertyTable hideDescription() { showDescription = false; return rebuild(); } /** * Rebuild the whole table * * @return this property table */ private PropertyTable rebuild() { widget = widget.disposeAndBuild(this); if (hasBeenBuilt) { setLayout(new FillLayout()); widget.build(); layout(); } return this; } /** * Update the component when some values has changed */ public void refreshValues() { rebuild(); } /** * Remove a change listener * * @param listener listener to remove */ public void removeChangeListener(final PTPropertyChangeListener listener) { changeListeners.remove(listener); } /** * @param newValues */ public void setProperties(final Map<String, Object> newValues) { for (final PTProperty prop : properties) { if (newValues == null) { prop.setValue(null); } else { final Object value = newValues.get(prop.getName()); prop.setValue(value); } } rebuild(); } /** * Show all buttons * * @return this property table */ public PropertyTable showButtons() { showButtons = true; return rebuild(); } /** * Show description * * @return this property table */ public PropertyTable showDescription() { showDescription = true; return rebuild(); } /** * Sort the properties * * @return this property table */ public PropertyTable sort() { sorted = true; widget.refillData(); return this; } /** * Show properties not sorted * * @return this property table */ public PropertyTable unsort() { sorted = false; widget.refillData(); return this; } /** * View the properties as categories * * @return this property table */ public PropertyTable viewAsCategories() { styleOfView = VIEW_AS_CATEGORIES; return rebuild(); } /** * View the properties as a flat list * * @return this property table */ public PropertyTable viewAsFlatList() { styleOfView = VIEW_AS_FLAT_LIST; return rebuild(); } }