Hi,
Thanks Mathias, sometimes someone have to tell what you have to do! 
I've created the binding.
It's very nice to see how easy is to customize the Spring RCP. Congratulations to the RCP Team!
Code:
/*
* $Id:$
* Wplex Software Ltda.
*/
package com.wplex.framework.client.form.binding;
/**
* Binder for <code>FullSelectionListBinding</code>.
*
* @author Mauro Ransolin
* @version $Revision:$
*/
public class FullSelectionListBinder extends ListBinder {
/**
* Key for holdingMode.
* @see FullSelectionListBinding.ListHoldingMode
*/
public static final String HOLDING_MODE_KEY = "holdingMode"; //$NON-NLS-1$
/**
* @see ListBinder#ListBinder()
*/
public FullSelectionListBinder() {
this(null, new String[] { SELECTABLE_ITEMS_KEY, COMPARATOR_KEY,
RENDERER_KEY, FILTER_KEY, SELECTION_MODE_KEY, HOLDING_MODE_KEY });
}
/**
* @see ListBinder#ListBinder(String[])
*/
public FullSelectionListBinder(String[] supportedContextKeys) {
this(null, supportedContextKeys);
}
/**
* @see ListBinder#ListBinder(Class, String[])
*/
public FullSelectionListBinder(Class requiredSourceClass,
String[] supportedContextKeys) {
super(requiredSourceClass, supportedContextKeys);
}
protected AbstractListBinding createListBinding(JComponent control,
FormModel formModel, String formPropertyPath) {
Assert.isInstanceOf(JList.class, control);
return new FullSelectionListBinding((JList) control, formModel,
formPropertyPath, getRequiredSourceClass());
}
protected void applyContext(AbstractListBinding binding, Map context) {
super.applyContext(binding, context);
FullSelectionListBinding listBinding = (FullSelectionListBinding) binding;
if (context.containsKey(HOLDING_MODE_KEY))
listBinding.setHoldingMode((ListHoldingMode) context
.get(HOLDING_MODE_KEY));
else
listBinding.setHoldingMode(ListHoldingMode.ALL_ITEMS);
}
}
Code:
/*
* $Id:$
* Wplex Software Ltda.
*/
package com.wplex.framework.client.form.binding;
/**
* A Binding that provides the option to hold all the values of the list,
* without the need of forcing full selection.
*
* @author Mauro Ransolin
* @version $Revision:$
*/
public class FullSelectionListBinding extends ListBinding {
private static final Object[] EMPTY_VALUES = new Object[0];
private final PropertyChangeListener valueModelListener = new ValueModelListener();
private final ListSelectionListener selectionListener = new SelectionListener();
private final ValueListener valueListener = new ValueListener();
boolean selectingValues;
private ListHoldingMode holdingMode;
public FullSelectionListBinding(JList list, FormModel formModel,
String formFieldPath, Class requiredSourceClass) {
super(list, formModel, formFieldPath, requiredSourceClass);
}
protected void updateSelectedItemsFromSelectionModel() {
if (ListHoldingMode.ALL_ITEMS.equals(this.holdingMode)) {
ListModel model = getList().getModel();
Object[] values;
if (model instanceof ObservableList) {
ObservableList oList = (ObservableList) model;
values = oList.toArray();
}
else
values = toArray(model);
if (!updateCollectionValue(values))
getValueModel().setValueSilently(convertSelectedValues(values),
this.valueModelListener);
}
else {
if (getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) {
Object singleValue = getList().getSelectedValue();
if (!updateCollectionValue(new Object[] { singleValue }))
getValueModel().setValueSilently(singleValue,
this.valueModelListener);
}
else {
Object[] values = getList().getSelectedValues();
if (!updateCollectionValue(values))
getValueModel().setValueSilently(
convertSelectedValues(getList().getSelectedValues()),
this.valueModelListener);
}
}
}
private Object[] toArray(ListModel model) {
Object[] array = new Object[model.getSize()];
for (int i = 0; i < model.getSize(); i++)
array[i] = model.getElementAt(i);
return array;
}
private boolean updateCollectionValue(Object[] values) {
if (Collection.class.isAssignableFrom(getPropertyType())) {
Collection<Object> value = (Collection<Object>) getValue();
if (value != null) {
try {
value.clear();
value.addAll(Arrays.asList(values));
return true;
}
catch (UnsupportedOperationException e) {
return false;
}
}
}
return false;
}
protected void doBindControl(ListModel bindingModel) {
JList list = getList();
list.setModel(bindingModel);
if (ListHoldingMode.ALL_ITEMS.equals(this.holdingMode))
getList().getModel().addListDataListener(this.valueListener);
else
list.getSelectionModel().addListSelectionListener(
this.selectionListener);
getValueModel().addValueChangeListener(this.valueModelListener);
if (!isPropertyConversionExecutorAvailable()
&& getSelectionMode() != ListSelectionModel.SINGLE_SELECTION) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Selection mode for list field " //$NON-NLS-1$
+ getProperty() + " forced to single selection." //$NON-NLS-1$
+ " If multiple selection is needed" //$NON-NLS-1$
+ " use a collection type" //$NON-NLS-1$
+ " (List, Collection, Object[])" //$NON-NLS-1$
+ " or provide a suitable converter" //$NON-NLS-1$
+ " to convert Object[] instances to property type " //$NON-NLS-1$
+ getPropertyType());
}
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
updateSelectedItemsFromValueModel();
}
/**
* Updates the selection model with the selected values from the value model.
*/
protected void updateSelectedItemsFromValueModel() {
Object value = getValue();
Object[] selectedValues = EMPTY_VALUES;
if (value != null) {
selectedValues = (Object[]) convertValue(value, Object[].class);
}
this.selectingValues = true;
try {
JList list = getList();
ListSelectionModel selectionModel = list.getSelectionModel();
selectionModel.setValueIsAdjusting(true);
try {
int[] valueIndexes = determineValueIndexes(selectedValues);
int selectionMode = getSelectionMode();
if (ListHoldingMode.SELECTED_ITEMS.equals(this.holdingMode)) {
if (selectionMode == ListSelectionModel.SINGLE_SELECTION
&& valueIndexes.length > 1)
list.setSelectedIndex(valueIndexes[0]);
else
list.setSelectedIndices(valueIndexes);
}
if (valueIndexes.length != selectedValues.length
&& !isReadOnly()
&& isEnabled()
|| (selectionMode == ListSelectionModel.SINGLE_SELECTION && valueIndexes.length > 1)) {
updateSelectedItemsFromSelectionModel();
}
}
finally {
selectionModel.setValueIsAdjusting(false);
}
}
finally {
this.selectingValues = false;
}
}
/**
* @param holdingMode
*/
public void setHoldingMode(ListHoldingMode holdingMode) {
this.holdingMode = holdingMode;
}
/**
* Defines the behaviour of ValueModel.
*/
public enum ListHoldingMode {
/**
* The ValueModel holds only the selected values, according with
* SELECTION_MODE.
*/
SELECTED_ITEMS,
/**
* The ValueModel holds all the values of the list, despite the
* SELECTION_MODE.
*/
ALL_ITEMS;
}
protected class ValueListener implements ListDataListener {
public void contentsChanged(ListDataEvent e) {
updateSelectedItemsFromSelectionModel();
}
public void intervalAdded(ListDataEvent e) {
updateSelectedItemsFromSelectionModel();
}
public void intervalRemoved(ListDataEvent e) {
updateSelectedItemsFromSelectionModel();
}
}
protected class ValueModelListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
updateSelectedItemsFromValueModel();
}
}
protected class SelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (!FullSelectionListBinding.this.selectingValues
&& !e.getValueIsAdjusting()) {
updateSelectedItemsFromSelectionModel();
}
}
}
}
BTW, if someone is interested, I've created the BinderSelectionStrategy, BinderFactory and the BinderFactoryProvider and can send by mail.
Thanks,
Mauro.