/******************************************************************************* * Copyright (c) 2007, Angelo Zerr 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: * Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation *******************************************************************************/ package org.eclipse.ufacekit.ui.swing.databinding.internal.swing; import java.awt.Container; import javax.swing.JList; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.eclipse.core.databinding.observable.Diffs; /** * Observe the selection of a widget which is a selection provider * * @since 1.0 * */ public abstract class SelectionProviderSingleSelectionObservableValue extends AbstractSwingObservableValue { private final ListSelectionModel model; private ListSelectionListener selectionListener; private boolean updating = false; private Object currentSelection; /** * Derived classes must call {@link #registerSelectionListener()} when they * are fully initialised to register the listener * * @param container * the component to observe * @param model * the list model backing the model of the column * * @since 1.0 */ private SelectionProviderSingleSelectionObservableValue(Container container, ListSelectionModel model) { super(container); this.model = model; } /** * Observe the selection of an JList * * @param list * the list whose selection is observed * @since 1.0 */ public SelectionProviderSingleSelectionObservableValue(JList list) { this(list, list.getSelectionModel()); } /** * Observe the selection of an JTable * * @param table * the table whose selection is observed * @since 1.0 */ public SelectionProviderSingleSelectionObservableValue(JTable table) { this(table, table.getSelectionModel()); } public synchronized void dispose() { super.dispose(); if (selectionListener != null) { model.removeListSelectionListener(selectionListener); } } public Object getValueType() { return null; } /** * Sets the selection to the provided <code>value</code>. Value change * events are fired after selection is set in the selection provider. * * @param value * object to set as selected, <code>null</code> if wanting to * remove selection */ public void doSetValue(final Object value) { try { updating = true; Object oldSelection = currentSelection; doSetSelectedValue(value); currentSelection = doGetValue(); if (!Util.equals(oldSelection, currentSelection)) { fireValueChange(Diffs.createValueDiff(oldSelection, currentSelection)); } } finally { updating = false; } } /** * Sets the selected value without having to raise any events as that is * done by the {@link #doSetValue(Object)} method. * * @param value * the value to set */ protected abstract void doSetSelectedValue(Object value); /** * Calls {@link #doGetValue()} and adds the selection listener to the model * so this method should only be called after the object is fully * initialized. */ protected void registerSelectionListener() { this.currentSelection = doGetValue(); selectionListener = new ListSelectionListener() { public void valueChanged(ListSelectionEvent event) { if (!updating) { Object oldSelection = currentSelection; currentSelection = doGetValue(); fireValueChange(Diffs.createValueDiff(oldSelection, currentSelection)); } } }; model.addListSelectionListener(selectionListener); } }