package no.ntnu.fp.gui; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; import java.net.URL; import javax.swing.AbstractListModel; import no.ntnu.fp.model.Person; import no.ntnu.fp.model.Project; /** * A ListModel implementation that wraps a Project object. * Makes it possible to directly view the Project's contained Persons in a * {@link javax.swing.JList}. It extends {@link javax.swing.AbstractListModel}, * to inherit support for listeners and firing events. * * @see javax.swing.AbstractListModel <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/AbstractListModel.html">javax.swing.AbstractListModel</a> * * @author Hallvard Tr�tteberg * @author Thomas Østerlie * * @version $Revision: 1.4 $ - $Date: 2005/02/22 07:54:10 $ */ class PersonListModel extends AbstractListModel implements PropertyChangeListener { /** * The data model that is wrapped */ private Project project; /** * Path to where the data model is saved. <code>null</code> means that the * user has not assigned a file to save the model. */ private URL url; /** * Default constructor. Initialises member variables. * * @param project The underlying data model * @param url Path to save the data model */ PersonListModel(Project project, URL url) { setProject(project); setUrl(url); } /** * Sets a new underlying data model. * * @param project The new underlying data model. */ void setProject(Project project) { if (this.project == project) { return; } if (this.project != null) { this.project.removePropertyChangeListener(this); } this.project = project; if (this.project != null) { this.project.addPropertyChangeListener(this); } } /** * Returns the underlying data model. * * @return The underlying data model. */ Project getProject() { return project; } /** * This method is defined in ListModel and * is called to get the number of element in the list. * In our case it is the number of Person objects in the project. * * @return the number of Person objects in the underlying Project object */ public int getSize() { return (project == null ? 0 : project.getPersonCount()); } /** * This method is defined in ListModel and * is called to get specific elements in the list. * In our case it returns the appropriate Person. * * @return the Person object at the specific position in the underlying Project object */ public Object getElementAt(int i) { try { return (project == null ? null : (Person)project.getPerson(i)); } catch (java.lang.IndexOutOfBoundsException e) { //handling of empty models return null; } } /** * This method is defined in ProjectListener and * is called to notify of changes in the Project structure or * to changes in the contained objects' properties * * @param event the ProjectEvent detailing what has changed */ public void propertyChange(PropertyChangeEvent event) { Object source = event.getSource(); Person person = null; int index; if ((source instanceof Project) && (event.getNewValue() instanceof Person)) { person = (Person)event.getNewValue(); index = project.indexOf(person); } else if ((source instanceof Project) && (event.getNewValue() instanceof Integer)) { person = (Person)event.getOldValue(); Integer i = (Integer)event.getNewValue(); index = i.intValue(); } else if (source instanceof Person) { person = (Person)source; index = project.indexOf(person); } else { return; } if ((source instanceof Project) && (event.getNewValue() instanceof Person)) fireIntervalAdded(project, index, index); else if ((source instanceof Project) && (event.getNewValue() instanceof Integer)) fireIntervalRemoved(project, index, index); else if (source instanceof Person) fireContentsChanged(project, index, index); } /** * Sets the path to save the data model. * * @param url The path. */ public void setUrl(URL url) { this.url = url; } /** * Get the path for the data model. Returns <code>null</code> if no path has been * assigned. * * @return The path */ public URL getUrl() { return url; } }