![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.cuf.model.ui.ListModelAdapter Maven / Gradle / Ivy
The newest version!
package net.sf.cuf.model.ui;
import java.util.List;
import net.sf.cuf.model.DelegateAccess;
import net.sf.cuf.model.SelectionInList;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.JComboBox;
import javax.swing.ComboBoxModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionListener;
/**
* A ListModelAdapter connects a model of a JList or a JComboBox to a SelectionInList
* ValueModel, the index for the selected list item is the index in the list/combobox.
* The data in the list/combobox is taken from the SelectionInList, too, and a
* DelegateAccess object may be used to convert from the "raw" object to a display object.
* Whenever either the selection of the list or the index of the
* ValueModel changes, the other model is adjusted accordingly.
* A ListModelAdapter is not a ValueModel itself, but connects a
* SelectionInList ValueModel to a ListSelectionModel and a ListModel/ComboBoxModel.
*/
public class ListModelAdapter implements ComboBoxModel, ListSelectionModel
{
/** list of listeners for our Swing ListModel, never null */
private EventListenerList mListenerList;
/** our delegate handling the Swing ListSelectionModel, never null */
private ListSelectionModel mListSelectionModel;
/** marker if we are inside a selection change, we then ignore selection
* changes from the "other" model */
private boolean mInSelectionChange;
/** value model holding the list, never null */
protected SelectionInList> mSelectionInList;
/** ValueModel to get the attribute, may be null */
private DelegateAccess mAccessValueModel;
/**
* Creates a new adapter between a SelectionInList ValueModel
* and a JList.
* @param pList the list for which we adapt to
* @param pListValueModel the value model (SelectionInList) that drives the list
* (data, selection) and gets updated by the list (selection only)
* @param pAccessValueModel null or the converter we use to map between the
* SelectionInList list objects and the display objects
* @throws IllegalArgumentException if pList or pValueModel is null
*/
public ListModelAdapter(final JList pList, final SelectionInList> pListValueModel,
final DelegateAccess pAccessValueModel)
{
if (pList==null)
throw new IllegalArgumentException("list must not be null");
if (pListValueModel==null)
throw new IllegalArgumentException("list value model must not be null");
mListSelectionModel= pList.getSelectionModel();
if (mListSelectionModel==null)
{
throw new IllegalArgumentException("list selection model must not be null");
}
mListSelectionModel.setSelectionMode(SINGLE_SELECTION);
mSelectionInList = pListValueModel;
mAccessValueModel = pAccessValueModel;
mListenerList = new EventListenerList();
mInSelectionChange= false;
mSelectionInList.onChangeSend (this, "vmDataChanged");
mSelectionInList.selectionHolder().onChangeSend(this, "vmSelectionChanged");
pList.setModel (this);
pList.setSelectionModel(this);
}
/**
* Creates a new adapter between a SelectionInList ValueModel
* and a JComboBox.
* @param pComboBox the combobox for which we adapt to
* @param pListValueModel the value model (SelectionInList) that drives the combobox
* (data, selection) and gets updated by the combobox (selection only)
* @param pAccessValueModel null or the converter we use to map between the
* SelectionInList list objects and the display objects
* @throws IllegalArgumentException if pComboBox or pValueModel is null
*/
public ListModelAdapter(final JComboBox pComboBox, final SelectionInList> pListValueModel, final DelegateAccess pAccessValueModel)
{
if (pComboBox==null)
throw new IllegalArgumentException("combobox must not be null");
if (pListValueModel==null)
throw new IllegalArgumentException("list value model must not be null");
mSelectionInList = pListValueModel;
mAccessValueModel = pAccessValueModel;
mListenerList = new EventListenerList();
mInSelectionChange= false;
mListSelectionModel = new DefaultListSelectionModel();
mListSelectionModel.setSelectionMode(SINGLE_SELECTION);
mSelectionInList.onChangeSend (this, "vmDataChanged");
mSelectionInList.selectionHolder().onChangeSend(this, "vmSelectionChanged");
pComboBox.setModel(this);
}
/**
* Notifies all listeners that something changed in our list model.
* @param pEvent the ListDataEvent to fire
*/
protected void fireListChanged(final ListDataEvent pEvent)
{
Object[] listeners = mListenerList.getListenerList();
for (int i= listeners.length-2; i>=0; i-=2)
{
if (listeners[i]==ListDataListener.class)
{
((ListDataListener)listeners[i+1]).contentsChanged(pEvent);
}
}
}
/**
* Callback from our VM
* @param pEvent not used
*/
@SuppressWarnings({"UnusedDeclaration"})
public void vmDataChanged(final ChangeEvent pEvent)
{
// notify the list to re-read the data, this will clear the selection,
// so we re-set the selection afterwards
int index = mSelectionInList.selectionHolder().intValue();
mInSelectionChange = true;
try
{
List> data= mSelectionInList.getValue();
int size= (data==null? 0: data.size());
ListDataEvent e = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, size);
fireListChanged(e);
if (index<0 || index>=size)
mListSelectionModel.clearSelection();
else
mListSelectionModel.setSelectionInterval(index, index);
}
finally
{
mInSelectionChange= false;
}
}
/**
* Callback from our VM
* @param pEvent not used
*/
@SuppressWarnings({"UnusedDeclaration"})
public void vmSelectionChanged(final ChangeEvent pEvent)
{
// ignore the changes we triggered
if (mInSelectionChange)
{
return;
}
mInSelectionChange= true;
try
{
// re-adjust the selection in our JList/JComboBox
int index= mSelectionInList.selectionHolder().intValue();
if (index==-1)
mListSelectionModel.clearSelection();
else
mListSelectionModel.setSelectionInterval(index, index);
ListDataEvent e = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index, index);
fireListChanged(e);
}
finally
{
mInSelectionChange= false;
}
}
/**
* Common Swing ComboBoxModel callback code
*/
private void handleListSelection()
{
// ignore the changes we triggered
if (mInSelectionChange)
{
return;
}
// ignore changes when the ListSelectionModel is adjusting
if (mListSelectionModel.getValueIsAdjusting())
{
return;
}
mInSelectionChange= true;
try
{
mSelectionInList.selectionHolder().setValue(mListSelectionModel.getMinSelectionIndex());
}
finally
{
mInSelectionChange= false;
}
}
public void setSelectionInterval(final int pIndex0, final int pIndex1)
{
mListSelectionModel.setSelectionInterval(pIndex0, pIndex1);
handleListSelection();
}
public void addSelectionInterval(final int pIndex0, final int pIndex1)
{
mListSelectionModel.addSelectionInterval(pIndex0, pIndex1);
handleListSelection();
}
public void removeSelectionInterval(final int pIndex0, final int pIndex1)
{
mListSelectionModel.removeSelectionInterval(pIndex0, pIndex1);
handleListSelection();
}
public void insertIndexInterval(final int pIndex, final int pLength, final boolean pBefore)
{
mListSelectionModel.insertIndexInterval(pIndex, pLength, pBefore);
handleListSelection();
}
public void removeIndexInterval(final int pIndex0, final int pIndex1)
{
mListSelectionModel.removeIndexInterval(pIndex0, pIndex1);
handleListSelection();
}
public void clearSelection()
{
mListSelectionModel.clearSelection();
handleListSelection();
}
public int getMinSelectionIndex()
{
return mListSelectionModel.getMinSelectionIndex();
}
public int getMaxSelectionIndex()
{
return mListSelectionModel.getMaxSelectionIndex();
}
public boolean isSelectedIndex(final int pIndex)
{
if (pIndex == -1)
{
return false;
}
return mListSelectionModel.isSelectedIndex(pIndex);
}
public int getAnchorSelectionIndex()
{
return mListSelectionModel.getAnchorSelectionIndex();
}
public void setAnchorSelectionIndex(final int pIndex)
{
mListSelectionModel.setAnchorSelectionIndex(pIndex);
handleListSelection();
}
public int getLeadSelectionIndex()
{
return mListSelectionModel.getLeadSelectionIndex();
}
public void setLeadSelectionIndex(final int pIndex)
{
mListSelectionModel.setLeadSelectionIndex(pIndex);
handleListSelection();
}
public boolean isSelectionEmpty()
{
return mListSelectionModel.isSelectionEmpty();
}
public void setValueIsAdjusting(final boolean pValueIsAdjusting)
{
if (pValueIsAdjusting!=mListSelectionModel.getValueIsAdjusting())
{
mListSelectionModel.setValueIsAdjusting(pValueIsAdjusting);
handleListSelection();
}
}
public boolean getValueIsAdjusting()
{
return mListSelectionModel.getValueIsAdjusting();
}
public void setSelectionMode(final int pSelectionMode)
{
if (pSelectionMode!= SINGLE_SELECTION)
{
throw new IllegalArgumentException("this selection model only supports single selection");
}
mListSelectionModel.setSelectionMode(pSelectionMode);
}
public int getSelectionMode()
{
return mListSelectionModel.getSelectionMode();
}
public void addListSelectionListener(final ListSelectionListener pListener)
{
mListSelectionModel.addListSelectionListener(pListener);
}
public void removeListSelectionListener(final ListSelectionListener pListener)
{
mListSelectionModel.removeListSelectionListener(pListener);
}
public Object getSelectedItem()
{
int index= mSelectionInList.getIndex();
return getElementAt(index);
}
public void setSelectedItem(final Object pItem)
{
int index= getIndexByObject(pItem);
setSelectionInterval(index, index);
}
/*
* Implementations of ListModel-Interface
*/
public Object getElementAt(final int pIndex)
{
if (pIndex==-1)
{
return null;
}
List> list = mSelectionInList.getValue();
Object value= list.get(pIndex);
if (mAccessValueModel != null)
{
value= mAccessValueModel.getValue(value);
}
return value;
}
public int getSize()
{
if (mSelectionInList.getValue() != null)
{
return mSelectionInList.getValue().size();
}
return 0;
}
public void addListDataListener(final ListDataListener pListener)
{
mListenerList.add(ListDataListener.class, pListener);
}
public void removeListDataListener(final ListDataListener pListener)
{
mListenerList.remove(ListDataListener.class, pListener);
}
/*
* Additional methods for our ListModel
*/
/**
* Add the item to the list.
* @see SelectionInList#addItem(Object)
*
* @param pObj the component to be added
*/
public void addElement(final Object pObj)
{
// i don't understand generics, but the cast helps to make the compiler happy, so ...
((SelectionInList)mSelectionInList).addItem(pObj);
}
/**
* Removes the item from the list.
* @see SelectionInList#removeItem(int)
*
* @param pObj the component to be removed
*/
public void removeElement(final Object pObj)
{
int index = getIndexByObject(pObj);
if (index >= 0)
{
mSelectionInList.removeItem(index);
}
}
/**
* Small helper to find a item in our list.
* The item may be of a different type than the entries in our list, if
* a DelegateAccess object is used for display conversion.
* @param pItem the (display) object we are searching
* @return -1 or the index of the item
*/
public int getIndexByObject(final Object pItem)
{
List> list = mSelectionInList.getValue();
if (list==null)
{
return -1;
}
int index = -1;
if(mAccessValueModel != null)
{
for (int i = 0, n = list.size(); i < n; i++)
{
Object item = mAccessValueModel.getValue(list.get(i));
// if the items are equal (including null==null);
//noinspection ObjectEquality
if (pItem==item || (pItem != null && pItem.equals(item)))
{
index= i;
break;
}
}
}
else
{
index = list.indexOf(pItem);
}
return index;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy