Author: tchemit Date: 2008-02-13 02:47:46 +0000 (Wed, 13 Feb 2008) New Revision: 891 Added: trunk/simexplorer-is/simexplorer-is-swing/src/java/fr/cemagref/simexplorer/is/ui/swing/model/HistoryModel.java Log: modele generique pour l'historique Added: trunk/simexplorer-is/simexplorer-is-swing/src/java/fr/cemagref/simexplorer/is/ui/swing/model/HistoryModel.java =================================================================== --- trunk/simexplorer-is/simexplorer-is-swing/src/java/fr/cemagref/simexplorer/is/ui/swing/model/HistoryModel.java (rev 0) +++ trunk/simexplorer-is/simexplorer-is-swing/src/java/fr/cemagref/simexplorer/is/ui/swing/model/HistoryModel.java 2008-02-13 02:47:46 UTC (rev 891) @@ -0,0 +1,175 @@ +/* +* \#\#% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin, +* Tony Chemit, Gabriel Landais +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* \#\#% */ +package fr.cemagref.simexplorer.is.ui.swing.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Modèle d'un historique générique. + * + * @author chemit + */ +public class HistoryModel<E> implements Serializable { + + /** la liste de données */ + protected List<E> data; + + /** la position actuellement utilisée */ + protected Integer currentIndex; + + /** la capacité de l'historique */ + protected int capacity; + + private static final long serialVersionUID = -6436315419371336090L; + + public HistoryModel(int capacity) { + this.capacity = capacity; + } + + /** + * Ajoute à l'historique une donnée après la position courante s'il y avait + * déjà des données ou en première position le cas échéant. + * <p/> + * Les données suivant la position courante sont supprimées. + * <p/> + * Si l'historique dépasse la capacité, on supprime la première donnée de + * l'historique + * + * @param e la donnée à ajouter + */ + public void add(E e) { + + if (size()>0) { + int newIndex = currentIndex + 1; + // il faut supprimer tous les elements au dela de la position courante + while (data.size() > newIndex) { + //TODO utiliser un container plus optimiserpour cette opération + // car ArrayList recopie à chaque fois l'ensemble du contenu + data.remove(newIndex); + } + } else { + data = new ArrayList<E>(); + } + data.add(e); + incrementIndex(); + if (data.size() > capacity) { + // on supprime le premier element de l'historique + data.remove(0); + } + } + + /** + * @return l'elemenet precedent par rapport a l'element courant + * @throws IllegalStateException si pas de data ou deja sur le premier element + */ + public E getPrevious() throws IllegalStateException { + checkHaveData(); + if (currentIndex == 0) { + throw new IllegalStateException("can not have previous data, already on first data in history"); + } + return data.get(currentIndex-1); + } + + /** + * @return l'elemenet precedent par rapport a l'element courant + * @throws IllegalStateException si pas de data ou deja sur le premier element + */ + public E gotoPrevious() throws IllegalStateException { + checkHaveData(); + if (currentIndex == 0) { + throw new IllegalStateException("can not have previous data, already on first data in history"); + } + decrementIndex(); + return data.get(currentIndex); + } + + /** + * @return l'element suivant par rapport a l'élément courant + * @throws IllegalStateException si pas de donnes ou deja sur le dernier + */ + public E getNext() throws IllegalStateException { + checkHaveData(); + if (currentIndex == data.size() - 1) { + throw new IllegalStateException("can not have next data, already on last data in history"); + } + return data.get(currentIndex+1); + } + + /** + * @return l'element suivant par rapport a l'élément courant + * @throws IllegalStateException si pas de donnes ou deja sur le dernier + */ + public E gotoNext() throws IllegalStateException { + checkHaveData(); + if (currentIndex == data.size() - 1) { + throw new IllegalStateException("can not have next data, already on last data in history"); + } + incrementIndex(); + return data.get(currentIndex); + } + + public E getCurrent() { + return size() == 0 || currentIndex == null ? null : data.get(currentIndex); + } + + public int size() { + return data == null ? 0 : data.size(); + } + + public boolean hasNext() { + return size() > 0 && currentIndex < data.size() - 1; + } + + public boolean hastPrevious() { + return size() > 0 && currentIndex > 0; + } + + public void clear() { + if (data != null) { + data.clear(); + } + currentIndex = null; + } + + /** + * Verifie s'il existe des donnees dans l'historique et declanche une exception + * si telle n'est pas le cas. + * + * @throws IllegalStateException si pas de donnees + */ + protected void checkHaveData() throws IllegalStateException { + if (data == null || data.isEmpty()) { + throw new IllegalStateException("no data in history"); + } + } + + protected void decrementIndex() { + currentIndex--; + } + + protected void incrementIndex() { + if (currentIndex == null) { + currentIndex = 0; + } else { + currentIndex++; + } + } +}