001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.component.pool;
020
021import icy.main.Icy;
022import icy.swimmingPool.SwimmingObject;
023import icy.swimmingPool.SwimmingPoolEvent;
024import icy.swimmingPool.SwimmingPoolListener;
025import icy.swimmingPool.WeakSwimmingPoolListener;
026import icy.util.StringUtil;
027
028import java.awt.Component;
029import java.awt.event.ActionEvent;
030import java.awt.event.ItemEvent;
031import java.util.ArrayList;
032import java.util.List;
033
034import javax.swing.DefaultComboBoxModel;
035import javax.swing.JComboBox;
036import javax.swing.JLabel;
037import javax.swing.JList;
038import javax.swing.ListCellRenderer;
039import javax.swing.SwingUtilities;
040
041/**
042 * @author Nicolas Chenouard
043 * @author Stephane
044 */
045public class SwimmingObjectChooser extends JComboBox implements SwimmingPoolListener
046{
047    public interface SwimmingObjectChooserListener
048    {
049        public void objectChanged(Object object);
050    }
051
052    private static final long serialVersionUID = 1594001236878708868L;
053
054    private List<SwimmingObjectChooserListener> listeners;
055    private final Class<? extends Object> itemClass;
056
057    public SwimmingObjectChooser(Class<? extends Object> itemClass)
058    {
059        this(itemClass, 50, "No valid object to display in SwimmingPool");
060    }
061
062    public SwimmingObjectChooser(Class<? extends Object> itemClass, final int maxSize, final String defaultMessage)
063    {
064        super();
065
066        this.itemClass = itemClass;
067        this.listeners = new ArrayList<SwimmingObjectChooserListener>();
068
069        Icy.getMainInterface().getSwimmingPool().addListener(new WeakSwimmingPoolListener(this));
070
071        this.setRenderer(new ListCellRenderer()
072        {
073            @Override
074            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
075                    boolean cellHasFocus)
076            {
077                if (value == null)
078                    return new JLabel(defaultMessage);
079
080                if (value instanceof SwimmingObject)
081                {
082                    JLabel label = new JLabel(StringUtil.limit(((SwimmingObject) value).getName(), maxSize));
083                    label.setToolTipText(((SwimmingObject) value).getName());
084                    return label;
085                }
086
087                return new JLabel(value.toString());
088            }
089        });
090    }
091
092    public Object getSelectedObject()
093    {
094        final Object o = getSelectedItem();
095
096        if (o != null)
097            return ((SwimmingObject) o).getObject();
098
099        return null;
100    }
101
102    @Override
103    public void swimmingPoolChangeEvent(final SwimmingPoolEvent event)
104    {
105        SwingUtilities.invokeLater(new Runnable()
106        {
107            @Override
108            public void run()
109            {
110                refreshList();
111
112                final SwimmingObject swimObj = event.getResult();
113
114                if (swimObj != null)
115                {
116                    final Object obj = swimObj.getObject();
117
118                    // Select the last entry computed
119                    if (obj != null)
120                        setSelectedItem(obj);
121                }
122            }
123        });
124
125    }
126
127    void refreshList()
128    {
129        // save old selection
130        final Object oldSelected = getSelectedItem();
131        // rebuild model
132        setModel(new DefaultComboBoxModel(getSwimmingObjects()));
133        // restore selection
134        setSelectedItem(oldSelected);
135    }
136
137    Object[] getSwimmingObjects()
138    {
139        final List<Object> objectList = new ArrayList<Object>();
140        final List<SwimmingObject> objects = Icy.getMainInterface().getSwimmingPool().getObjects();
141
142        for (SwimmingObject so : objects)
143            if (itemClass.isInstance(so.getObject()))
144                objectList.add(so);
145
146        return objectList.toArray();
147    }
148
149    public void addListener(SwimmingObjectChooserListener listener)
150    {
151        if (!listeners.contains(listener))
152            listeners.add(listener);
153    }
154
155    public void removeListener(SwimmingObjectChooserListener listener)
156    {
157        listeners.remove(listener);
158    }
159
160    @Override
161    public void fireItemStateChanged(ItemEvent e)
162    {
163        for (SwimmingObjectChooserListener listener : listeners)
164            listener.objectChanged(getSelectedObject());
165
166        super.fireItemStateChanged(e);
167    }
168
169    @Override
170    public void actionPerformed(ActionEvent e)
171    {
172        for (SwimmingObjectChooserListener listener : listeners)
173            listener.objectChanged(getSelectedObject());
174
175        super.actionPerformed(e);
176    }
177}