001: package com.silvermindsoftware.hitch.swing;
002:
003: import javax.swing.*;
004: import javax.swing.text.DocumentFilter;
005: import javax.swing.text.AttributeSet;
006: import javax.swing.text.BadLocationException;
007: import java.text.ParseException;
008:
009: /**
010: * Copyright 2007 Brandon Goodin
011: *
012: * Licensed under the Apache License, Version 2.0 (the "License");
013: * you may not use this file except in compliance with the License.
014: * You may obtain a copy of the License at
015: *
016: * http://www.apache.org/licenses/LICENSE-2.0
017: *
018: * Unless required by applicable law or agreed to in writing, software
019: * distributed under the License is distributed on an "AS IS" BASIS,
020: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
021: * See the License for the specific language governing permissions and
022: * limitations under the License.
023: */
024:
025: /**
026: * ListFormatter provides completion while text is being input
027: * into the JFormattedTextField.Completion is only done if the
028: * user is inserting text at the end of the document.Completion
029: * is done by way of the SpinnerListModel method findNextMatch.
030: * This is largely a copy of the SpinnerListFormatter found in
031: * JDK 1.5 sources. A new version was written because the JDK
032: * version was not extensible and did not allow for the ability
033: * to ehance the stringToValue.
034: *
035: * The stringToValue was enhanced to iterate through the model
036: * list and compare the String values of the list objects and
037: * the string value passed to the formatter. The first equal
038: * will return. So, if multiple objects have the same toString
039: * value, only the first will be returned.
040: */
041: public class EnhancedSpinnerListFormatter extends
042: JFormattedTextField.AbstractFormatter {
043: private DocumentFilter filter;
044: private EnhancedSpinnerListModel model;
045:
046: public EnhancedSpinnerListFormatter(EnhancedSpinnerListModel model) {
047: this .model = model;
048: }
049:
050: public String valueToString(Object value) throws ParseException {
051: if (value == null) {
052: return "";
053: }
054: return value.toString();
055: }
056:
057: public Object stringToValue(String string) throws ParseException {
058:
059: for (Object item : model.getList()) {
060: if (item.toString().equals(string))
061: return item;
062: }
063: return null;
064: }
065:
066: protected DocumentFilter getDocumentFilter() {
067: if (filter == null) {
068: filter = new Filter();
069: }
070: return filter;
071: }
072:
073: private class Filter extends DocumentFilter {
074: public void replace(FilterBypass fb, int offset, int length,
075: String string, AttributeSet attrs)
076: throws BadLocationException {
077: if (string != null
078: && (offset + length) == fb.getDocument()
079: .getLength()) {
080: Object next = model.findNextMatch(fb.getDocument()
081: .getText(0, offset)
082: + string);
083: String value = (next != null) ? next.toString() : null;
084:
085: if (value != null) {
086: fb.remove(0, offset + length);
087: fb.insertString(0, value, null);
088: getFormattedTextField().select(
089: offset + string.length(), value.length());
090: return;
091: }
092: }
093: super .replace(fb, offset, length, string, attrs);
094: }
095:
096: public void insertString(FilterBypass fb, int offset,
097: String string, AttributeSet attr)
098: throws BadLocationException {
099: replace(fb, offset, 0, string, attr);
100: }
101: }
102: }
|