001: /*
002: * This is free software, licensed under the Gnu Public License (GPL)
003: * get a copy from <http://www.gnu.org/licenses/gpl.html>
004: * $Id: EnumeratedPropertyHolder.java,v 1.6 2004/03/07 14:22:02 hzeller Exp $
005: * author: Henner Zeller <H.Zeller@acm.org>
006: */
007: package henplus.property;
008:
009: import java.util.Iterator;
010: import java.util.Collection;
011:
012: import henplus.view.util.NameCompleter;
013:
014: /**
015: * A PropertyHolder, that can change its values to a fixed set of
016: * values.
017: */
018: public abstract class EnumeratedPropertyHolder extends PropertyHolder {
019: private final String _values[];
020: private final NameCompleter _completer;
021:
022: /**
023: * create a new EnumeratedPropertyHolder that gets an array of
024: * Strings with possible values of this property.
025: *
026: * @param enumeratedValues the Values this property can take.
027: */
028: public EnumeratedPropertyHolder(String[] enumeratedValues) {
029: _values = enumeratedValues;
030: _completer = new NameCompleter(enumeratedValues);
031: }
032:
033: /**
034: * same with collection as Input.
035: */
036: public EnumeratedPropertyHolder(Collection values) {
037: this ((String[]) values.toArray(new String[values.size()]));
038: }
039:
040: /**
041: * do not override this method but the
042: * {@link #enumeratedPropertyChanged(int, String)} method instead.
043: */
044: protected final String propertyChanged(String newValue)
045: throws Exception {
046: if (newValue == null) {
047: throw new Exception("'null' not a valid value");
048: }
049: newValue = newValue.trim();
050:
051: Iterator possibleValues = _completer.getAlternatives(newValue);
052: if (possibleValues == null || !possibleValues.hasNext()) {
053: StringBuffer expected = new StringBuffer();
054: for (int i = 0; i < _values.length; ++i) {
055: if (i != 0)
056: expected.append(", ");
057: expected.append(_values[i]);
058: }
059: throw new Exception("'" + newValue
060: + "' does not match any of [" + expected.toString()
061: + "]");
062: }
063:
064: String value = (String) possibleValues.next();
065: if (possibleValues.hasNext()) {
066: StringBuffer matching = new StringBuffer(value);
067: do {
068: matching.append(", ");
069: matching.append((String) possibleValues.next());
070: } while (possibleValues.hasNext());
071:
072: throw new Exception("'" + newValue
073: + "' ambiguous. Matches [" + matching.toString()
074: + "]");
075: }
076:
077: int index = -1;
078: // small size of array -- linear search acceptable
079: for (int i = 0; i < _values.length; ++i) {
080: if (value.equals(_values[i])) {
081: index = i;
082: break;
083: }
084: }
085:
086: enumeratedPropertyChanged(index, value);
087: return value;
088: }
089:
090: /**
091: * to be overridden to get informed of the change and veto
092: * it.
093: * @param index the index of the property that changed
094: * @param value the new value of that property
095: * @throws Exception to veto that change.
096: */
097: protected abstract void enumeratedPropertyChanged(int index,
098: String value) throws Exception;
099:
100: public Iterator completeValue(String partialValue) {
101: return _completer.getAlternatives(partialValue);
102: }
103: }
104:
105: /*
106: * Local variables:
107: * c-basic-offset: 4
108: * compile-command: "ant -emacs -find build.xml"
109: * End:
110: */
|