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.type.collection.list;
020
021import icy.preferences.XMLPreferences;
022import icy.type.collection.list.RecentListEvent.RecentListEventType;
023
024import java.util.ArrayList;
025
026import javax.swing.event.EventListenerList;
027
028/**
029 * @author stephane
030 */
031public abstract class RecentList
032{
033    public final static String ID_ENTRY = "entry";
034
035    protected final XMLPreferences preferences;
036    protected final int nbMaxEntry;
037    protected final ArrayList<Object> list;
038
039    private final EventListenerList listeners;
040
041    public RecentList(XMLPreferences preferences, int nbMaxEntry)
042    {
043        super();
044
045        this.preferences = preferences;
046        this.nbMaxEntry = nbMaxEntry;
047        list = new ArrayList<Object>();
048        listeners = new EventListenerList();
049
050        // load the list from prefs
051        load();
052    }
053
054    public void clear()
055    {
056        synchronized (list)
057        {
058            list.clear();
059        }
060
061        // save to pref
062        save();
063        // inform about change
064        changed();
065    }
066
067    public void addEntry(Object entry)
068    {
069        synchronized (list)
070        {
071            // remove entry if already present
072            list.remove(entry);
073            // add entry at top
074            list.add(0, entry);
075
076            // remove last entries
077            while (list.size() > nbMaxEntry)
078                list.remove(list.size() - 1);
079        }
080
081        // save to pref
082        save();
083        // inform about change
084        changed();
085    }
086
087    public int getSize()
088    {
089        return list.size();
090    }
091
092    public int getMaxSize()
093    {
094        return nbMaxEntry;
095    }
096
097    public Object getEntry(int index)
098    {
099        return list.get(index);
100    }
101
102    protected void load()
103    {
104        synchronized (list)
105        {
106            list.clear();
107
108            for (int i = 0; i < nbMaxEntry; i++)
109            {
110                final Object value = loadEntry(ID_ENTRY + i);
111                if (value != null)
112                    list.add(value);
113            }
114        }
115
116        changed();
117    }
118
119    protected abstract Object loadEntry(final String key);
120
121    protected void save()
122    {
123        // clear all
124        preferences.clear();
125        preferences.removeChildren();
126        preferences.clean();
127
128        synchronized (list)
129        {
130            // then save each entry
131            for (int i = 0; i < nbMaxEntry; i++)
132            {
133                if (i < list.size())
134                    saveEntry(ID_ENTRY + i, list.get(i));
135                else
136                    saveEntry(ID_ENTRY + i, null);
137            }
138        }
139    }
140
141    protected abstract void saveEntry(final String key, final Object value);
142
143    /**
144     * process on change
145     */
146    protected void changed()
147    {
148        final RecentListEvent event = new RecentListEvent(this, RecentListEventType.CHANGED);
149        // notify listeners we have changed
150        fireEvent(event);
151    }
152
153    /**
154     * Add a listener
155     * 
156     * @param listener
157     */
158    public void addListener(RecentListListener listener)
159    {
160        listeners.add(RecentListListener.class, listener);
161    }
162
163    /**
164     * Remove a listener
165     * 
166     * @param listener
167     */
168    public void removeListener(RecentListListener listener)
169    {
170        listeners.remove(RecentListListener.class, listener);
171    }
172
173    /**
174     * fire event
175     * 
176     * @param e
177     */
178    public void fireEvent(RecentListEvent e)
179    {
180        for (RecentListListener listener : listeners.getListeners(RecentListListener.class))
181            listener.RencentFileChanged(e);
182    }
183}