001    package users.swing;
002    
003    import util.*;
004    import util.swing.*;
005    
006    import users.*;
007    import users.events.*;
008    import java.io.*;
009    import java.util.*;
010    
011    /**
012     * A {@link javax.swing.table.TableModel} that models the contents of a {@link UserManager}.
013     *
014     * @author Thomas Medack
015     * @version 3.0 12/06/2001
016     * @since v3.0
017     */
018    public class UserTableModel extends AbstractTableModel implements UserDataListener, HelpableListener,
019            Serializable {
020    
021        /**
022             * ID for serialization.
023             */
024            private static final long serialVersionUID = 4455959788476630698L;
025    
026            /**
027         * The UserManager that is being modelled.
028         *
029         * @serial
030         */
031        protected UserManager m_umManager;
032    
033        /**
034         * This abstract class is a special Comparator, which compares Users. It will be
035         * used in the UserTableModel to define the order of elements in the assoziated
036         * JUserTable.
037         *
038         * @serial
039         */
040        public static abstract class UserComparator implements Serializable {
041            public abstract int compare(User obj, User obj1);
042        }
043    
044        /**
045         * The Comparator that defines the sorting order of records in the model. It compares
046         * {@link User Users}.
047         *
048         * @serial
049         */
050       // /*protected UserComparator m_cmpComparator = new UserComparator() {
051       //     public int compare (User obj, User obj1) {
052       //          return new NaturalComparator().compare (obj.getName(), obj1.getName());
053       //     }
054       //      };*/
055    
056        protected Comparator<User> m_cmpComparator = new NaturalComparator<User>();
057    
058        /**
059         * The internal model. A list of the Users' names.
060         *
061         * @serial
062         */
063        protected List<User> m_lKeys;
064        
065        /**
066         * Set the table's data. Data is {@link users.UserManager}
067         */
068            public void setData(Object n_umManager) {
069                    m_umManager = (UserManager) n_umManager;
070                    updateModel();
071                    fireTableDataChanged();
072            }
073    
074        /**
075         * Create a new UserTableModel.
076         *
077         * @param u the UserManager to be modelled.
078         * @param cmp a Comparator defining the sort order of the records. If <code>null</code>, records are ordered
079         * according to the natural ordering of the Users.
080         * @param ted a TableEntryDescriptor that can split individual Users into a table's cells.
081         */
082        public UserTableModel(UserManager u, Comparator<User> cmp, TableEntryDescriptor ted) {
083            super(ted);
084            m_umManager = u;
085    
086            if (cmp != null) {
087                m_cmpComparator = cmp;
088            }
089    
090            listenerList = new ListenerHelper(this);
091    
092            updateModel();
093        }
094    
095        /**
096         * Get the record at the given index.
097         *
098         * @param row the index for which to retrieve the record. Element of [0, {@link #getRowCount}).
099         * @return the {@link User} to be displayed at the given index. May return <code>null</code> if
100         * either there is no record at the indicated position or an exception occurs.
101         *
102         * @override Never
103         */
104        public Object getRecord(int row) {
105            ((ListenerHelper)listenerList).needModelUpdate();
106    
107            if ((row > -1) && (row < getRowCount())) {
108                return m_lKeys.get(row);
109            } else {
110                return null;
111            }
112        }
113    
114        /**
115         * Get the number of records in this model.
116         *
117         * @override Never
118         */
119        public int getRowCount() {
120            ((ListenerHelper)listenerList).needModelUpdate();
121    
122            return m_lKeys.size();
123        }
124    
125        /**
126         * Subscribe as a listener to the model.
127         *
128         * @override Never
129         */
130        public void subscribe() {
131            m_umManager.addUserDataListener(this);
132        }
133    
134        /**
135         * Un-Subscribe as a listener from the model.
136         *
137         * @override Never
138         */
139        public void unsubscribe() {
140            m_umManager.removeUserDataListener(this);
141        }
142    
143        /**
144         * Update the internal model based on the modelled {@link UserManager}.
145         *
146         * @override Never
147         */
148        public synchronized void updateModel() {
149            List<User> lKeys = new LinkedList<User>(m_umManager.getUsers());
150            Collections.sort(lKeys, new Comparator<User>() {
151                public int compare(User u1, User u2) {
152                    return m_cmpComparator.compare(u1, u2);
153                }
154            });
155    
156            m_lKeys = lKeys;
157        }
158    
159        public void userAdded(UserDataEvent e) {
160            updateModel();
161    
162            int nIdx = m_lKeys.indexOf(e.getUser());
163    
164            if (nIdx > -1) {
165                fireTableRowsInserted(nIdx, nIdx);
166            }
167        }
168    
169        public void userDeleted(UserDataEvent e) {
170            int nIdx = m_lKeys.indexOf(e.getUser());
171    
172            updateModel();
173            if (nIdx > -1) {
174                fireTableRowsDeleted(nIdx, nIdx);
175            }
176        }
177    }