001: /* SimpleListModel.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Thu Aug 18 15:40:14 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zul;
020:
021: import java.util.LinkedList;
022: import java.util.List;
023: import java.util.Arrays;
024: import java.util.Comparator;
025:
026: import org.zkoss.util.ArraysX;
027: import org.zkoss.zul.event.ListDataEvent;
028:
029: /**
030: * A simple implementation of {@link ListModel}.
031: * Note: It assumes the content is immutable. If not, use {@link ListModelList}
032: * or {@link ListModelArray} nstead.
033: *
034: * @author tomyeh
035: * @see ListModelArray
036: * @see ListModelSet
037: * @see ListModelList
038: * @see ListModelMap
039: * @see ListSubModel (since 3.0.2)
040: */
041: public class SimpleListModel extends AbstractListModel implements
042: ListModelExt, ListSubModel, java.io.Serializable {
043: private static final long serialVersionUID = 20060707L;
044:
045: private final Object[] _data;
046:
047: /** Constructor.
048: *
049: * @param data the array to represent
050: * @param live whether to have a 'live' {@link ListModel} on top of
051: * the specified list.
052: * If false, the content of the specified list is copied.
053: * If true, this object is a 'facade' of the specified list,
054: * i.e., when you add or remove items from this ListModelList,
055: * the inner "live" list would be changed accordingly.
056: *
057: * However, it is not a good idea to modify <code>data</code>
058: * once it is passed to this method with live is true,
059: * since {@link Listbox} is not smart enough to hanle it.
060: * @since 2.4.1
061: */
062: public SimpleListModel(Object[] data, boolean live) {
063: if (data == null)
064: throw new NullPointerException();
065: _data = live ? data : (Object[]) ArraysX.clone(data);
066: }
067:
068: /** Constructor.
069: * It made a copy of the specified array (<code>data</code>).
070: */
071: public SimpleListModel(Object[] data) {
072: this (data, false);
073: }
074:
075: /** Constructor.
076: * @since 2.4.1
077: */
078: public SimpleListModel(List data) {
079: _data = data.toArray(new Object[data.size()]);
080: }
081:
082: //-- ListModel --//
083: public int getSize() {
084: return _data.length;
085: }
086:
087: public Object getElementAt(int j) {
088: return _data[j];
089: }
090:
091: //-- ListModelExt --//
092: /** Sorts the data.
093: *
094: * @param cmpr the comparator.
095: * @param ascending whether to sort in the ascending order.
096: * It is ignored since this implementation uses cmprt to compare.
097: */
098: public void sort(Comparator cmpr, final boolean ascending) {
099: Arrays.sort(_data, cmpr);
100: fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1);
101: }
102:
103: /**
104: * Returns the subset of the list model data that matches
105: * the specified value.
106: * It is ususally used for implmentation of auto-complete.
107: *
108: * <p>The implementation uses {@link #objectToString} to convert
109: * the returned object of {@link #getElementAt} to the string.
110: * And then, an element is considered as 'matched', if the string
111: * starts with the specified value.
112: *
113: * <p>Note: If the nRows is a negative number, 10 is assumed.
114: *
115: * @param value the value to retrieve the subset of the list model.
116: * It is converted to a string first by use of {@link #objectToString}.
117: * Then, it is used to check if an element starts with (aka., prefix with)
118: * this string.
119: * @since 3.0.2
120: */
121: public ListModel getSubModel(Object value, int nRows) {
122: final String idx = value == null ? "" : objectToString(value);
123: if (nRows < 0)
124: nRows = 10;
125: final LinkedList data = new LinkedList();
126: for (int i = 0; i < _data.length; i++) {
127: if (idx.equals("") || _data[i].toString().startsWith(idx)) {
128: data.add(_data[i]);
129: if (--nRows <= 0)
130: break; //done
131: }
132: }
133: return new SimpleListModel(data);
134: }
135:
136: /**
137: * Returns the string from the value object. It is used to convert
138: * the object type to the string type for {@link #getSubModel(Object, int)}.
139: *
140: * <p>The implementation uses {@link Object#toString} to convert
141: * the value to a string (and to an empty string if null).
142: * If you need better control, you can override this method.
143: *
144: * @param value the value object.
145: * @since 3.0.2
146: */
147: protected String objectToString(Object value) {
148: return value != null ? value.toString() : "";
149: }
150: }
|