Author: sletellier Date: 2012-07-02 12:51:21 +0200 (Mon, 02 Jul 2012) New Revision: 2362 Url: http://nuiton.org/repositories/revision/jaxx/2362 Log: - refs #2146 : Add widget to select values in list - Add genericListListener - Introduce ListSelectorModel Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListEvent.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListListener.java trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelectorModel.java Modified: trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/editor/ListSelectorDemo.jaxx trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListModel.java trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelector.jaxx trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListToListSelector.jaxx trunk/src/site/rst/tutoriels.rst Modified: trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/editor/ListSelectorDemo.jaxx =================================================================== --- trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/editor/ListSelectorDemo.jaxx 2012-06-30 00:38:05 UTC (rev 2361) +++ trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/editor/ListSelectorDemo.jaxx 2012-07-02 10:51:21 UTC (rev 2362) @@ -31,6 +31,7 @@ jaxx.demo.entities.DemoDataProvider jaxx.demo.entities.DemoDecoratorProvider jaxx.runtime.swing.renderer.DecoratorProviderListCellRenderer + java.util.Collection </import> <ListCellRenderer id='listCellRenderer' initializer='new DecoratorProviderListCellRenderer(new DemoDecoratorProvider())'/> @@ -40,9 +41,9 @@ <String id='removeToolTip' javaBean='"Remove"'/> <script><![CDATA[ -public List<People> getSelectedActors() { +public List<People> getActors(Collection<Movie> movies) { List<People> actors = Lists.newArrayList(); - for (Movie m : comboToListSelector.getSelectedValues()) { + for (Movie m : movies) { List<People> actorsToAdd = m.getActors(); actors.removeAll(actorsToAdd); actors.addAll(actorsToAdd); @@ -81,8 +82,8 @@ removeToolTip='{getRemoveToolTip()}' values='{dataProvider.getMovies()}' renderer='{listCellRenderer}' - onIntervalAdded='listToListSelector.setValues(getSelectedActors())' - onIntervalRemoved='listToListSelector.setValues(getSelectedActors())'/> + onValuesAdded='listToListSelector.setValues(getActors(comboToListSelector.getSelectedValues()))' + onValuesRemoved='listToListSelector.setValues(getActors(comboToListSelector.getSelectedValues()))'/> </JScrollPane> </cell> </row> Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListEvent.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListEvent.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListEvent.java 2012-07-02 10:51:21 UTC (rev 2362) @@ -0,0 +1,44 @@ +/* + * #%L + * JAXX :: Runtime + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2008 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.model; + +import java.util.Collection; +import java.util.EventObject; + +/** + * @author sletellier <letellier@codelutin.com> + */ +public class GenericListEvent<B> extends EventObject { + + protected Collection<B> values; + + public GenericListEvent(Object source, Collection<B> values) { + super(source); + this.values = values; + } + + public Collection<B> getValues() { + return values; + } +} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListListener.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListListener.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListListener.java 2012-07-02 10:51:21 UTC (rev 2362) @@ -0,0 +1,40 @@ +/* + * #%L + * JAXX :: Runtime + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2008 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing.model; + +import java.util.EventListener; + +/** + * @author sletellier <letellier@codelutin.com> + */ +public interface GenericListListener extends EventListener { + + void valuesAdded(GenericListEvent event); + + void valuesRemoved(GenericListEvent event); + + void selectionAdded(GenericListEvent event); + + void selectionRemoved(GenericListEvent event); +} Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListModel.java 2012-06-30 00:38:05 UTC (rev 2361) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/model/GenericListModel.java 2012-07-02 10:51:21 UTC (rev 2362) @@ -26,10 +26,12 @@ import com.google.common.collect.Lists; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.util.Collection; import java.util.List; import javax.swing.ComboBoxModel; import javax.swing.DefaultListModel; import javax.swing.DefaultListSelectionModel; +import javax.swing.event.EventListenerList; import javax.swing.event.ListDataListener; /** @@ -37,6 +39,7 @@ */ public class GenericListModel<B> extends DefaultListSelectionModel implements ComboBoxModel { + protected EventListenerList listenerList = new EventListenerList(); protected final PropertyChangeSupport pcs = new PropertyChangeSupport(this); public static final String PROPERTY_SELECTED_VALUE = "selectedValues"; @@ -49,21 +52,32 @@ this.selectedValues = Lists.newArrayList(); } - public void setElements(List<B> values) { + public void setElements(Collection<B> values) { + Collection<B> oldValues = getElements(); + Collection<B> oldSelectedValues = getSelectedValues(); clearSelection(); + fireSelectionRemoved(oldSelectedValues); + clearElements(); + fireValuesRemoved(oldValues); + for (B value : values) { - addElement(value); + delegate.addElement(value); } + + fireSelectionAdded(values); } public void clearElements() { + Collection<B> elements = getElements(); delegate.clear(); + + fireValuesRemoved(elements); } - public List<B> getElements() { + public Collection<B> getElements() { int size = delegate.getSize(); - List<B> result = Lists.newArrayList(); + Collection<B> result = Lists.newArrayList(); for (int i=0;i<size;i++) { result.add((B) delegate.get(i)); } @@ -72,50 +86,63 @@ public void addElement(int index, B valueToAdd) { delegate.add(index, valueToAdd); + + fireValuesAdded(Lists.newArrayList(valueToAdd)); } public void addElement(B valueToAdd) { delegate.addElement(valueToAdd); + + fireValuesAdded(Lists.newArrayList(valueToAdd)); } - public void addElements(List<B> valuesToAdd) { + public void addElements(Collection<B> valuesToAdd) { for (B value : valuesToAdd) { - addElement(value); + delegate.addElement(value); } + + fireValuesAdded(valuesToAdd); } - public List<B> getSelectedValues() { + public Collection<B> getSelectedValues() { return Lists.newArrayList(selectedValues); } - public void removeElements(List<B> values) { + public void removeElements(Collection<B> values) { for (B value : values) { delegate.removeElement(value); } unSelectItems(values); + + fireValuesRemoved(values); } - protected void unSelectItems(List<B> values) { - List<B> oldValue = Lists.newArrayList(selectedValues); + protected void unSelectItems(Collection<B> values) { + Collection<B> oldValue = Lists.newArrayList(selectedValues); for (B value : values) { int index = selectedValues.indexOf(value); removeSelectionIntervalWithoutFire(index, index); } + fireSelectionRemoved(values); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } protected void unSelectItem(B value) { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); int index = selectedValues.indexOf(value); removeSelectionIntervalWithoutFire(index, index); + + fireSelectionRemoved(Lists.newArrayList(value)); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } public void addSelectedItem(B toSelect) { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); selectedValues.add(toSelect); int index = selectedValues.indexOf(toSelect); super.addSelectionInterval(index, index); + + fireSelectionAdded(Lists.newArrayList(toSelect)); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @@ -125,25 +152,38 @@ @Override public void addSelectionInterval(int index0, int index1) { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); + addSelectionIntervalWithFire(index0, index1); super.addSelectionInterval(index0, index1); + + Collection<B> newValue = Lists.newArrayList(selectedValues); + newValue.removeAll(oldValue); + fireSelectionAdded(newValue); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @Override public void setSelectionInterval(int index0, int index1) { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); selectedValues.clear(); addSelectionIntervalWithFire(index0, index1); super.setSelectionInterval(index0, index1); + + Collection<B> newValue = Lists.newArrayList(selectedValues); + newValue.removeAll(oldValue); + fireSelectionAdded(newValue); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @Override public void removeSelectionInterval(int index0, int index1) { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); removeSelectionIntervalWithoutFire(index0, index1); + + Collection<B> newValue = Lists.newArrayList(selectedValues); + newValue.removeAll(oldValue); + fireSelectionRemoved(newValue); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @@ -178,9 +218,11 @@ @Override public void clearSelection() { - List<B> oldValue = Lists.newArrayList(selectedValues); + Collection<B> oldValue = Lists.newArrayList(selectedValues); selectedValues.clear(); super.clearSelection(); + + fireSelectionRemoved(oldValue); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @@ -191,8 +233,12 @@ @Override public void setSelectedItem(Object anItem) { - List<B> oldValue = this.selectedValues; + Collection<B> oldValue = this.selectedValues; + fireSelectionRemoved(selectedValues); + selectedValues = Lists.newArrayList((B)anItem); + + fireSelectionAdded(selectedValues); firePropertyChange(PROPERTY_SELECTED_VALUE, oldValue, selectedValues); } @@ -224,6 +270,14 @@ delegate.removeListDataListener(l); } + public void addGenericListListener(GenericListListener l) { + listenerList.add(GenericListListener.class, l); + } + + public void removeGenericListListener(GenericListListener l) { + listenerList.remove(GenericListListener.class, l); + } + public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } @@ -240,6 +294,74 @@ pcs.removePropertyChangeListener(propertyName, listener); } + protected void fireValuesAdded(Collection<B> values) { + if (values.isEmpty()) { + return; + } + Object[] listeners = listenerList.getListenerList(); + GenericListEvent<B> e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == GenericListListener.class) { + if (e == null) { + e = new GenericListEvent<B>(this, values); + } + ((GenericListListener)listeners[i+1]).valuesAdded(e); + } + } + } + + protected void fireValuesRemoved(Collection<B> values) { + if (values.isEmpty()) { + return; + } + Object[] listeners = listenerList.getListenerList(); + GenericListEvent<B> e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == GenericListListener.class) { + if (e == null) { + e = new GenericListEvent<B>(this, values); + } + ((GenericListListener)listeners[i+1]).valuesRemoved(e); + } + } + } + + protected void fireSelectionAdded(Collection<B> selectedValues) { + if (selectedValues.isEmpty()) { + return; + } + Object[] listeners = listenerList.getListenerList(); + GenericListEvent<B> e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == GenericListListener.class) { + if (e == null) { + e = new GenericListEvent<B>(this, selectedValues); + } + ((GenericListListener)listeners[i+1]).selectionAdded(e); + } + } + } + + protected void fireSelectionRemoved(Collection<B> selectedValues) { + if (selectedValues.isEmpty()) { + return; + } + Object[] listeners = listenerList.getListenerList(); + GenericListEvent<B> e = null; + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == GenericListListener.class) { + if (e == null) { + e = new GenericListEvent<B>(this, selectedValues); + } + ((GenericListListener)listeners[i+1]).selectionAdded(e); + } + } + } + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { pcs.firePropertyChange(propertyName, oldValue, newValue); } Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelector.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelector.jaxx 2012-06-30 00:38:05 UTC (rev 2361) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelector.jaxx 2012-07-02 10:51:21 UTC (rev 2362) @@ -34,16 +34,24 @@ java.beans.PropertyChangeListener javax.swing.event.ListDataListener jaxx.runtime.swing.model.GenericListModel + jaxx.runtime.swing.model.GenericListListener + java.util.Collection </import> <String id='addToolTip' javaBean='"+"'/> <String id='removeToolTip' javaBean='"-"'/> + <ListSelectorModel id='model' + genericType='B' + javaBean='null'/> + <GenericListModel id='fromModel' + elements='{model.getValues()}' genericType='B'/> <GenericListModel id='toModel' + elements='{model.getSelectedValues()}' genericType='B'/> <Boolean id='addEnabled' javaBean='Boolean.FALSE'/> @@ -68,44 +76,64 @@ }); } -public void setValues(List<B> values) { +public void addValues(Collection<B> values) { + toModel.removeElements(values); + fromModel.removeElements(values); + fromModel.addElements(values); +} + +public void removeValues(Collection<B> values) { + toModel.removeElements(values); + fromModel.removeElements(values); +} + +public void setValues(Collection<B> values) { toModel.clearElements(); fromModel.setElements(values); } -public List<B> getValues() { +public Collection<B> getValues() { return fromModel.getElements(); } -public void setSelectedValues(List<B> selectedValues) { +public void setSelectedValues(Collection<B> selectedValues) { fromModel.removeElements(selectedValues); toModel.setElements(selectedValues); } -public List<B> getSelectedValues() { +public Collection<B> getSelectedValues() { return toModel.getElements(); } public void add() { - moveSelect(fromModel, toModel); + Collection<B> selectedValues = moveSelect(fromModel, toModel); + if (model != null) { + model.add(selectedValues); + } } public void remove() { - moveSelect(toModel, fromModel); + Collection<B> selectedValues = moveSelect(toModel, fromModel); + if (model != null) { + model.remove(selectedValues); + } } -protected void moveSelect(GenericListModel<B> from, GenericListModel<B> to) { - List<B> selectedValues = from.getSelectedValues(); - from.removeElements(selectedValues); +protected Collection<B> moveSelect(GenericListModel<B> from, GenericListModel<B> to) { + Collection<B> selectedValues = Lists.newArrayList(from.getSelectedValues()); + if (model == null) { + from.removeElements(selectedValues); + } to.addElements(selectedValues); + return selectedValues; } -public void addListDataListener(ListDataListener l) { - toModel.addListDataListener(l); +public void addGenericListListener(GenericListListener l) { + toModel.addGenericListListener(l); } -public void removeListDataListener(ListDataListener l) { - toModel.removeListDataListener(l); +public void removeGenericListListener(GenericListListener l) { + toModel.removeGenericListListener(l); } ]]> </script> Added: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelectorModel.java =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelectorModel.java (rev 0) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListSelectorModel.java 2012-07-02 10:51:21 UTC (rev 2362) @@ -0,0 +1,90 @@ +/* + * #%L + * JAXX :: Widgets + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2008 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package jaxx.runtime.swing; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Collection; + +/** + * @author sletellier <letellier@codelutin.com> + */ +public abstract class ListSelectorModel<B> { + + protected final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + public static final String PROPERTY_SELECTED_VALUES = "selectedValues"; + public static final String PROPERTY_VALUES = "values"; + + protected Collection<B> values; + protected Collection<B> selectedValues; + + public Collection<B> getValues() { + return values; + } + + public void setValues(Collection<B> values) { + Collection<B> oldValues = getValues(); + this.values = values; + firePropertyChange(PROPERTY_VALUES, oldValues, values); + } + + public Collection<B> getSelectedValues() { + return selectedValues; + } + + public void setSelectedValues(Collection<B> selectedValues) { + Collection<B> oldValue = getSelectedValues(); + this.selectedValues = selectedValues; + firePropertyChange(PROPERTY_SELECTED_VALUES, oldValue, selectedValues); + } + + public abstract void add(Collection<B> values); + + public abstract void remove(Collection<B> values); + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + pcs.firePropertyChange(propertyName, oldValue, newValue); + } + + protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) { + pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue); + } +} Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListToListSelector.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListToListSelector.jaxx 2012-06-30 00:38:05 UTC (rev 2361) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/ListToListSelector.jaxx 2012-07-02 10:51:21 UTC (rev 2362) @@ -35,7 +35,9 @@ cellRenderer='{getRenderer()}'/> </cell> <cell anchor='north'> - <JToolBar id='actions' floatable='false' orientation='{SwingConstants.VERTICAL}'> + <JToolBar id='actions' + floatable='false' + orientation='{SwingConstants.VERTICAL}'> <JButton id="add" toolTipText='{getAddToolTip()}' actionIcon='select' Modified: trunk/src/site/rst/tutoriels.rst =================================================================== --- trunk/src/site/rst/tutoriels.rst 2012-06-30 00:38:05 UTC (rev 2361) +++ trunk/src/site/rst/tutoriels.rst 2012-07-02 10:51:21 UTC (rev 2362) @@ -1,3 +1,26 @@ +.. - +.. * #%L +.. * JAXX +.. * $Id:$ +.. * $HeadURL:$ +.. * %% +.. * Copyright (C) 2008 - 2012 CodeLutin +.. * %% +.. * This program is free software: you can redistribute it and/or modify +.. * it under the terms of the GNU Lesser General Public License as +.. * published by the Free Software Foundation, either version 3 of the +.. * License, or (at your option) any later version. +.. * +.. * This program is distributed in the hope that it will be useful, +.. * but WITHOUT ANY WARRANTY; without even the implied warranty of +.. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.. * GNU General Lesser Public License for more details. +.. * +.. * You should have received a copy of the GNU General Lesser Public +.. * License along with this program. If not, see +.. * <http://www.gnu.org/licenses/lgpl-3.0.html>. +.. * #L% +.. - ========= Tutoriels =========