001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: OrderedListModel.java,v $ 023 Revision 1.3 2004/05/13 21:40:59 markl 024 javadoc updates 025 026 Revision 1.2 2004/05/05 22:40:38 markl 027 comment block updates 028 029 Revision 1.1 2004/03/16 06:15:15 markl 030 new class 031 ---------------------------------------------------------------------------- 032*/ 033 034package kiwi.ui.model; 035 036import kiwi.util.*; 037 038import java.text.*; 039import java.util.*; 040import javax.swing.*; 041import javax.swing.event.*; 042 043/** An implementation of <i>ListModel</i> that keeps its elements ordered. 044 * 045 * @author Mark Lindner 046 * @since Kiwi 2.0 047 */ 048 049public class OrderedListModel implements ListModel 050 { 051 private Vector data = new Vector(); 052 private Vector listeners = new Vector(); 053 private Collator collator; 054 055 /** Construct a new, empty <code>OrderedListModel</code>. 056 */ 057 058 public OrderedListModel() 059 { 060 collator = Collator.getInstance(); 061 collator.setStrength(Collator.SECONDARY); // ignore case 062 } 063 064 /** Construct a new <code>OrderedListModel</code> with the given data. 065 * 066 * @param data A collection of elements to insert into the model. The 067 * elements are inserted in sorted order. 068 */ 069 070 public OrderedListModel(Vector data) 071 { 072 this(); 073 074 this.data.addAll(data); 075 076 Collections.sort(this.data); 077 } 078 079 /** Set the collator to be used by this model. 080 * 081 * @param collator The collator. 082 */ 083 084 public void setCollator(Collator collator) 085 { 086 this.collator = collator; 087 } 088 089 /** Add a list data listener to this model's list of listeners. 090 * 091 * @param listener The listener to add. 092 */ 093 094 public void addListDataListener(ListDataListener listener) 095 { 096 listeners.addElement(listener); 097 } 098 099 /** Remove a list data listener from this model's list of listeners. 100 * 101 * @param listener The listener to remove. 102 */ 103 104 public void removeListDataListener(ListDataListener listener) 105 { 106 listeners.removeElement(listener); 107 } 108 109 /** Get the size of the model. 110 * 111 * @return The number of items in the model. 112 */ 113 114 public int getSize() 115 { 116 return(data.size()); 117 } 118 119 /** Get the object at the given index in the model. 120 * 121 * @param index The index of the object to retrieve. 122 * @return The object at the given index, or <code>null</code> if the index 123 * is out of range. 124 */ 125 126 public Object getElementAt(int index) 127 { 128 return(data.elementAt(index)); 129 } 130 131 /** Add an object to the model. The object is inserted at the proper index 132 * to maintain a sorted model. 133 * 134 * @param elem The new object to add. 135 */ 136 137 public void addElement(Object elem) 138 { 139 int index = Collections.binarySearch(data, elem, collator); 140 if(index < 0) 141 { 142 index = -index - 1; 143 144 data.insertElementAt(elem, index); 145 fireIntervalAdded(index, index); 146 } 147 } 148 149 /** Remove all elements from the model. */ 150 151 public void clear() 152 { 153 if(! data.isEmpty()) 154 { 155 int sz = data.size(); 156 data.clear(); 157 fireIntervalRemoved(0, sz - 1); 158 } 159 } 160 161 /** Determine if the model contains an object. 162 * 163 * @param elem The object to search for. 164 * @return <code>true</code> if the object is in the model, 165 * <code>false</code> otherwise. 166 */ 167 168 public boolean contains(Object elem) 169 { 170 return(data.contains(elem)); 171 } 172 173 /** Get an enumeration of the elements in the model. */ 174 175 public Enumeration elements() 176 { 177 return(data.elements()); 178 } 179 180 /** Get the index of an element in the model. */ 181 182 public int indexOf(Object elem) 183 { 184 return(data.indexOf(elem)); 185 } 186 187 /** Determine if the model is empty. 188 * 189 * @return <code>true</code> if there are no elements in the model, 190 * <code>false</code> otherwise. 191 */ 192 193 public boolean isEmpty() 194 { 195 return(data.isEmpty()); 196 } 197 198 /** Remove an element at the given index in the model. 199 * 200 * @param index The index of the element to remove. 201 */ 202 203 public void removeElementAt(int index) 204 { 205 if((index >= 0) && (index < data.size())) 206 { 207 data.removeElementAt(index); 208 fireIntervalRemoved(index, index); 209 } 210 } 211 212 /** Remove a range of elements form the model. 213 * 214 * @param fromIndex The starting index of the range. 215 * @param toIndex The ending index of the range. 216 */ 217 218 public void removeRange(int fromIndex, int toIndex) 219 { 220 if((fromIndex >= 0) && (toIndex < data.size()) && (fromIndex <= toIndex)) 221 { 222 int ct = toIndex - fromIndex; 223 224 for(int i = 0; i < ct; i++) 225 data.removeElementAt(fromIndex); 226 227 fireIntervalRemoved(fromIndex, toIndex); 228 } 229 } 230 231 /** Fire an <i>interval added</i> event. 232 * 233 * @param start The starting index of the interval. 234 * @param end The ending index of the interval. 235 */ 236 237 protected void fireIntervalAdded(int start, int end) 238 { 239 ListDataEvent evt = null; 240 241 Enumeration e = listeners.elements(); 242 while(e.hasMoreElements()) 243 { 244 ListDataListener l = (ListDataListener)e.nextElement(); 245 if(evt == null) 246 evt = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, start, 247 end); 248 249 l.intervalAdded(evt); 250 } 251 } 252 253 /** Fire an <i>interval removed</i> event. 254 * 255 * @param start The starting index of the interval. 256 * @param end The ending index of the interval. 257 */ 258 259 protected void fireIntervalRemoved(int start, int end) 260 { 261 ListDataEvent evt = null; 262 263 Enumeration e = listeners.elements(); 264 while(e.hasMoreElements()) 265 { 266 ListDataListener l = (ListDataListener)e.nextElement(); 267 if(evt == null) 268 evt = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, start, 269 end); 270 271 l.intervalRemoved(evt); 272 } 273 } 274 275 /** Fire a <i>contents changed</i> event. */ 276 277 protected void fireContentsChanged() 278 { 279 ListDataEvent evt = null; 280 281 Enumeration e = listeners.elements(); 282 while(e.hasMoreElements()) 283 { 284 ListDataListener l = (ListDataListener)e.nextElement(); 285 if(evt == null) 286 evt = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, 287 data.size() - 1); 288 289 l.contentsChanged(evt); 290 } 291 } 292 293 } 294 295/* end of source file */