/*
Copyright (c) 2003-2008 ITerative Consulting Pty Ltd. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package DisplayProject;
import java.awt.Component;
import java.io.Serializable;
import javax.swing.JComponent;
import javax.swing.ListModel;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import DisplayProject.binding.ListElementValueModelConverter;
import DisplayProject.binding.TypeAwareValueModel;
import DisplayProject.binding.list.SelectionInList;
import DisplayProject.events.ChildEventHelper;
import DisplayProject.events.ClientEventManager;
import Framework.Array_Of_ListElement;
import Framework.CloneHelper;
import Framework.IntegerNullable;
import Framework.ListElement;
import Framework.NumericData;
import Framework.TextData;
import Framework.TextNullable;
/**
* This model is used by {@link DisplayProject.RadioList}
*
*/
@SuppressWarnings("serial")
public class RadioListModel implements ListModel, Serializable, ListSelectionListener, ListField {
private RadioList rl = null;
//private ListElement current;
protected SelectionInList list;
public RadioListModel() {
super();
}
public RadioListModel(SelectionInList pModel, RadioList pList) {
super();
this.list = pModel;
this.rl = pList;
//pList.setSelectionModel( new SingleListSelectionAdapter(
//this.list.getSelectionIndexHolder()));
}
public RadioList getRadioList() {
return rl;
}
public void setRadioList(RadioList rl) {
this.rl = rl;
}
public Object getElementAt(int index) {
return this.list.getElementAt(index);
//return rl.getElementList().get(index);
}
public int getSize() {
return this.list.getSize();
//return rl.getElementList().size();
}
public void addListDataListener(ListDataListener l) {
this.list.addListDataListener(l);
}
public void removeListDataListener(ListDataListener l) {
this.list.removeListDataListener(l);
}
public void valueChanged(ListSelectionEvent ev) {
if (!ev.getValueIsAdjusting()){
//ListElement le = (ListElement)rl.getSelectedValue();
ClientEventManager.postEvent( ev.getSource(), "AfterValueChange" );
UIutils.setDataChangedFlag((JComponent)ev.getSource());
// TF:27/9/07:Revamped to use new event poster
ChildEventHelper.postEventToAllParents((Component)ev.getSource(), "ChildAfterValueChange");
}
}
public int getIntegerValue() {
if (rl != null)
return rl.getIntegerValue();
else
return -1;
}
public Object getObjectValue() {
if (rl != null)
return rl.getObjectValue();
else
return null;
}
public TextData getTextValue() {
if (rl != null)
return rl.getTextValue();
else
return null;
}
public void setIntegerValue(int value) {
if (rl != null)
rl.setIntegerValue(value);
}
public void setObjectValue(Object value) {
if (rl != null)
rl.setObjectValue(value);
}
public void setTextValue(TextData value) {
if (rl != null)
rl.setTextValue(value);
}
public Array_Of_ListElement<ListElement> getElementList() {
return rl.getElementList();
}
public boolean isNullableType() {
Class<?> mappedClass = null;
if (this.list.getSelectionHolder() instanceof ListElementValueModelConverter) {
mappedClass = ((ListElementValueModelConverter)this.list.getSelectionHolder()).getSubjectType();
}
else if (this.list.getSelectionHolder() instanceof TypeAwareValueModel) {
mappedClass = ((TypeAwareValueModel)this.list.getSelectionHolder()).getValueType();
}
if (mappedClass != null) {
return TextNullable.class.isAssignableFrom(mappedClass) || IntegerNullable.class.isAssignableFrom(mappedClass);
}
return false;
}
public void setElementList(Array_Of_ListElement<ListElement> les) {
// TF:8/8/07:Made a shallow clone in case there is a really big object attached to the list element
Array_Of_ListElement<ListElement> clonedList = CloneHelper.clone(les, false);
Object currentValue = this.list.getValue();
ListElement valueToReselect = null;
if (currentValue instanceof ListElement && clonedList != null && this.list.getSelectionHolder() instanceof TypeAwareValueModel) {
TypeAwareValueModel tavm = (TypeAwareValueModel)this.list.getSelectionHolder();
// We need to find an item in the new list which is the same as an item in the old list,
// depending on the type being considered. For example, if the list is mapped to an int,
// we need to find an element in the new list with the same IntegerValue.
Class<?> clazz = tavm.getValueType();
ListElement currentSelection = (ListElement)currentValue;
for (ListElement item : clonedList) {
if (clazz.equals(Integer.TYPE) ||
clazz.equals(Short.TYPE) ||
NumericData.class.isAssignableFrom(clazz) ||
Number.class.isAssignableFrom(clazz)) {
if (item.getIntegerValue() == currentSelection.getIntegerValue()) {
valueToReselect = item;
break;
}
}
else if (String.class.isAssignableFrom(clazz) || TextData.class.isAssignableFrom(clazz) && currentSelection.getTextValue() != null) {
if (currentSelection.getTextValue().equals(item.getTextValue())) {
valueToReselect = item;
break;
}
}
else {
if (currentSelection.getObjectValue() != null && currentSelection.getObjectValue() == item.getObjectValue()) {
valueToReselect = item;
break;
}
}
}
}
this.list.setList(clonedList);
rl.setElementList(clonedList);
this.list.setValue(currentValue);
// TF:19/08/2009:DET-108:if a value is already set, then retain the selection
if (valueToReselect == null) {
// TF:19/3/08:Added check in for allowing deselect, as nullable types will allow a clear index value
if (this.list.getValue() == null && clonedList.size() > 0 && !rl.getAllowDeselect()) {
// Always default the first one in the list if needed
this.list.setValue(les.get(0));
rl.setSelectedIndex(0);
}
else {
// We need to clear the selection. HOwever, if there currently is no
// selection, clearing it will do nothing, yet we need to force it to
// map the underlying data to null. Hence, we set the selection first if we can.
if (clonedList.size() > 0) {
this.rl.setSelectedIndex(0);
}
this.rl.clearSelection();
}
}
else {
rl.setSelectedValue(valueToReselect, true);
}
this.rl.invalidate();
}
public int getSelectedIndex() {
return rl.getSelectedIndex();
}
public void setSelectedIndex(int index) {
rl.setSelectedIndex(index);
}
/* (non-Javadoc)
* @see DisplayProject.ListField#setElementSelected(int, boolean)
* @author AD:26/5/2008
*/
public void setElementSelected(int index, boolean isSelected) {
rl.setElementSelected(index, isSelected);
}
}