package users.swing; import javax.swing.*; import java.util.*; import users.*; import users.events.*; import util.*; /** * A ListModel modelling the set or a subset of users managed by a UserManager. * * @see UserManager * @see User * * @author Steffen Zschaler * @version 2.0 05/05/1999 * @since v2.0 */ public class UserListModel extends AbstractListModel implements UserDataListener, HelpableListener { /** * A local copy of the list of users to provide easy and consistent access via an * index. * * This model is kept up to date by registering as a listener with the UserManager. * * @serial */ protected List m_lUsers; /** * A Comparator that orders the users. By default, users are ordered by their name. * * @serial */ protected Comparator m_cmpComparator = new SerializableComparator() { public int compare (Object o1, Object o2) { return ((User) o1).getName().compareTo (((User) o2).getName()); } }; /** * A filter that defines the subset of users that are displayed. If <code>null</code> no * filtering will occur. * * @serial */ protected UserFilter m_ufFilter; /** * The UserManager that is being modelled. * * @serial */ protected UserManager m_um; /** * Create a new UserListModel modelling the global UserManager. All Users will be displayed and they will be * sorted by their names. */ public UserListModel() { this (UserManager.getGlobalUM()); } /** * Create a new UserListModel modelling the global UserManager. * * @param uf a filter that defines the set of users to be displayed. If <code>null</code>, no filtering will * occur. * @param cmp a Comparator that defines the order of the users to be displayed. The objects to be compared * by this comparator will be Users. If <code>null</code>, users will be ordered by their names. */ public UserListModel (UserFilter uf, Comparator cmp) { this (UserManager.getGlobalUM(), uf, cmp); } /** * Create a new UserListModel modelling a given UserManager. All Users will be displayed and they will be * sorted by their names. * * @param um the UserManager to be modelled. */ public UserListModel (UserManager um) { this (um, null, null); } /** * Create a new UserListModel modelling a given UserManager. * * @param um the UserManager to be modelled. * @param uf a filter that defines the set of users to be displayed. If <code>null</code>, no filtering will * occur. * @param cmp a Comparator that defines the order of the users to be displayed. The objects to be compared * by this comparator will be Users. If <code>null</code>, users will be ordered by their names. */ public UserListModel (UserManager um, UserFilter uf, Comparator cmp) { super(); // replace listener list for special support listenerList = new ListenerHelper (this); m_um = um; m_ufFilter = uf; if (cmp != null) { m_cmpComparator = cmp; } updateModel(); } // List Model methods /** * Return the number of users in the model. * * @return the number of users in the model. * * @override Never */ public int getSize() { // make sure internal model is up to date. ((ListenerHelper) listenerList).needModelUpdate(); return m_lUsers.size(); } /** * Get a user by index. * * @param nIndex the index of the user to be returned. * * @return the user associated with the given index. * * @override Never */ public Object getElementAt (int nIndex) { // make sure internal model is up to date. ((ListenerHelper) listenerList).needModelUpdate(); return m_lUsers.get (nIndex); } // UserDataListener methods /** * Respond to the <code>userAdded</code> event by updating the internal model * and forwarding a translated version of the event to anyone who listens to us. * * @param e the event object describing the event. * * @override Sometimes */ public void userAdded (UserDataEvent e) { updateModel(); int nPos = m_lUsers.indexOf (e.getUser()); if (nPos > -1) { fireIntervalAdded (this, nPos, nPos); } } /** * Respond to the <code>userDeleted</code> event by updating the internal model * and forwarding a translated version of the event to anyone who listens to us. * * @param e the event object describing the event. * * @override Sometimes */ public void userDeleted (UserDataEvent e) { int nPos = m_lUsers.indexOf (e.getUser()); updateModel(); if (nPos > -1) { fireIntervalRemoved (this, nPos, nPos); } } // HelpableListener methods /** * Update the internal model. * * @override Sometimes */ public synchronized void updateModel() { List lUsers = new LinkedList (m_um.getUsers()); if (m_ufFilter != null) { for (Iterator i = lUsers.iterator(); i.hasNext();) { if (!m_ufFilter.match ((User) i.next())) { i.remove(); } } } Collections.sort (lUsers, m_cmpComparator); m_lUsers = lUsers; } /** * Subscribe to the UserManager to be informed of any changes in its set of users. * * @override Never */ public void subscribe() { m_um.addUserDataListener (this); } /** * Unsubscribe from the UserManager as there is no need to listen to it anymore, as * we are not listened to anymore. From now on we are working in "poll-mode" until * any listener indicates an interest in us again. * * @override Never */ public void unsubscribe() { m_um.removeUserDataListener (this); } }