/******************************************************************************* * Copyright (c) 2000, 2010 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.draw2d; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; /** * A ButtonGroup holds a group of {@link Clickable Clickable's} models and * provides unique selection in them. There is capability to add a default * selection. Models who want to belong to the group should just add themselves * to this group. By doing so they listen to this group for changes. * <p> * Setting of the default selection results in its being selected any time * {@link #setSelected(ButtonModel, boolean)} is called. If no default selection * is set, the last entry selected is not allowed to deselect. */ public class ButtonGroup { private ButtonModel selectedModel; private ButtonModel defaultModel; private List members = new ArrayList(); private List listeners = new ArrayList(); /** * Constructs a ButtonGroup with no default selection. * * @since 2.0 */ public ButtonGroup() { } /** * Adds the passed ButtonModel to the ButtonGroup. * * @param model * ButtonModel to be added to this group * @since 2.0 */ public void add(ButtonModel model) { if (!members.contains(model)) { model.setGroup(this); members.add(model); } } /** * Adds the passed listener. ButtonGroups use PropertyChangeListeners to * react to selection changes in the ButtonGroup. * * @param listener * Listener to be added to this group * @since 2.0 */ public void addPropertyChangeListener(PropertyChangeListener listener) { listeners.add(listener); } /** * Fires a PropertyChangeEvent to all PropertyChangeListeners added to this * ButtonGroup. * * @param oldValue * Old selection value * @param newValue * New selection value * @since 2.0 */ protected void firePropertyChange(Object oldValue, Object newValue) { PropertyChangeEvent event = new PropertyChangeEvent(this, ButtonModel.SELECTED_PROPERTY, oldValue, newValue); for (int i = 0; i < listeners.size(); i++) ((PropertyChangeListener) listeners.get(i)).propertyChange(event); } /** * Returns the ButtonModel which is selected by default for this * ButtonGroup. * * @return The default ButtonModel * @since 2.0 */ public ButtonModel getDefault() { return defaultModel; } /** * Returns a List which contains all of the {@link ButtonModel ButtonModels} * added to this ButtonGroup. * * @return The List of ButtonModels in this ButtonGroup * @since 2.0 */ public List getElements() { return members; } /** * Returns the ButtonModel for the currently selected button. * * @return The ButtonModel for the currently selected button * @since 2.0 */ public ButtonModel getSelected() { return selectedModel; } /** * Determines if the given ButtonModel is selected or not. * * @param model * Model being tested for selected status * @return Selection state of the given model * @since 2.0 */ public boolean isSelected(ButtonModel model) { return (model == getSelected()); } /** * Removes the given ButtonModel from this ButtonGroup. * * @param model * ButtonModel being removed * @since 2.0 */ public void remove(ButtonModel model) { if (getSelected() == model) setSelected(getDefault(), true); if (defaultModel == model) defaultModel = null; members.remove(model); } /** * Removes the passed PropertyChangeListener from this ButtonGroup. * * @param listener * PropertyChangeListener to be removed * @since 2.0 */ public void removePropertyChangeListener(PropertyChangeListener listener) { listeners.remove(listener); } /** * Sets the passed ButtonModel to be the currently selected ButtonModel of * this ButtonGroup. Fires a property change. * * @param model * ButtonModel to be selected * @since 2.0 */ protected void selectNewModel(ButtonModel model) { ButtonModel oldModel = selectedModel; selectedModel = model; if (oldModel != null) oldModel.setSelected(false); firePropertyChange(oldModel, model); } /** * Sets the default selection of this ButtonGroup. Does nothing if it is not * present in the group. Sets selection to the passed ButtonModel. * * @param model * ButtonModel which is to be the default selection. * @since 2.0 */ public void setDefault(ButtonModel model) { defaultModel = model; if (getSelected() == null && defaultModel != null) defaultModel.setSelected(true); } /** * Sets the button with the given ButtonModel to be selected. * * @param model * The ButtonModel to be selected * @since 2.0 */ public void setSelected(ButtonModel model) { if (model == null) selectNewModel(null); else model.setSelected(true); } /** * Sets model to the passed state. * <p> * If <i>value</i> is * <ul> * <li><code>true</code>: * <ul> * <li>The passed ButtonModel will own selection. * </ul> * <li><code>false</code>: * <ul> * <li>If the passed model owns selection, it will lose selection, and * selection will be given to the default ButonModel. If no default * ButtonModel was set, selection will remain as it was, as one ButtonModel * must own selection at all times. * <li>If the passed model does not own selection, then selection will * remain as it was. * </ul> * </ul> * * @param model * The model to be affected * @param value * The selected state * @since 2.0 */ public void setSelected(ButtonModel model, boolean value) { if (value) { if (model == getSelected()) return; selectNewModel(model); } else { if (model != getSelected()) return; if (getDefault() == null) return; getDefault().setSelected(true); } } }