001/*
002 * $Id: ListComboBoxModel.java 3935 2011-03-02 19:06:41Z kschaefe $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 * 
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 * Lesser General Public License for more details.
016 * 
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020 */
021package org.jdesktop.swingx.combobox;
022
023import java.awt.event.ActionEvent;
024import java.awt.event.ActionListener;
025import java.util.List;
026
027import javax.swing.AbstractListModel;
028import javax.swing.ComboBoxModel;
029
030/**
031 * A {@code ComboBoxModel} for {@code List}s.
032 *
033 * @param <E> the type of elements maintained by the list backing this model
034 * 
035 * @author jm158417
036 * @author Karl George Schaefer
037 */
038public class ListComboBoxModel<E> extends AbstractListModel implements ComboBoxModel, ActionListener {
039    /**
040     * A key used to notify the model that the backing {@code List} has changed.
041     */
042    public static final String UPDATE = "update";
043    
044    /**
045     * A reference to the list backing this model.
046     * <p>
047     * This model does <b>not</b> make a copy of the list, so any changes in
048     * the list without synchronizing the model may have drastic effects.
049     */
050    protected final List<E> data;
051    
052    /**
053     * The currently selected item.
054     */
055    protected E selected;
056    
057    /**
058     * Creates a {@code ListComboBoxModel} backed by the supplied {@code list}.
059     * 
060     * @param list
061     *                the list backing this model
062     * @throws NullPointerException
063     *                 if {@code list} is {@code null}
064     */
065    public ListComboBoxModel(List<E> list) {
066        this.data = list;
067        
068        if(list.size() > 0) {
069            selected = list.get(0);
070        }
071    }
072    
073    /**
074     * Set the selected item. The implementation of this method should notify
075     * all registered {@code ListDataListener}s that the contents have changed.
076     * 
077     * @param item
078     *                the list object to select or {@code null} to clear the
079     *                selection
080     * @throws ClassCastException
081     *                 if {@code item} is not of type {@code E}
082     */
083    @Override
084    @SuppressWarnings("unchecked")
085    public void setSelectedItem(Object item) {
086        if ((selected != null && !selected.equals(item))
087                || selected == null && item != null) {
088            selected = (E) item;
089            fireContentsChanged(this, -1, -1);
090        }
091    }
092    
093    /**
094     * {@inheritDoc}
095     */
096    @Override
097    public E getSelectedItem() {
098        return this.selected;
099    }
100    
101    /**
102     * {@inheritDoc}
103     */
104    @Override
105    public E getElementAt(int index) {
106        return data.get(index);
107    }
108    
109    /**
110     * {@inheritDoc}
111     */
112    @Override
113    public int getSize() {
114        return data.size();
115    }
116    
117    /**
118     * {@inheritDoc}
119     */
120    @Override
121    public void actionPerformed(ActionEvent evt) {
122        if(evt.getActionCommand().equals(UPDATE)) {
123            this.fireContentsChanged(this, 0, getSize() - 1);
124        }
125    }
126}