Methods Summary |
---|
java.lang.Object | adjustValue(java.lang.Object value, java.util.Map attributes, java.lang.Object field, int direction)Subclasses supporting incrementing must override this to handle
the actual incrementing. value is the current value,
attributes gives the field the cursor is in (may be
null depending upon canIncrement ) and
direction is the amount to increment by.
return null;
|
boolean | canIncrement(java.lang.Object field, int cursorPosition)Returns true if field is non-null.
Subclasses that wish to allow incrementing to happen outside of
the known fields will need to override this.
return (field != null);
|
boolean | canReplace(ReplaceHolder rh)Overriden in an attempt to honor the literals.
If we do
not allow invalid values and are in overwrite mode, this does the
following for each character in the replacement range:
- If the character is a literal, add it to the string to replace
with. If there is text to insert and it doesn't match the
literal, then insert the literal in the the middle of the insert
text. This allows you to either paste in literals or not and
get the same behavior.
- If there is no text to insert, replace it with ' '.
If not in overwrite mode, and there is text to insert it is
inserted at the next non literal index going forward. If there
is only text to remove, it is removed from the next non literal
index going backward.
if (!getAllowsInvalid()) {
String text = rh.text;
int tl = (text != null) ? text.length() : 0;
if (tl == 0 && rh.length == 1 && getFormattedTextField().
getSelectionStart() != rh.offset) {
// Backspace, adjust to actually delete next non-literal.
rh.offset = getNextNonliteralIndex(rh.offset, -1);
}
if (getOverwriteMode()) {
StringBuffer replace = null;
for (int counter = 0, textIndex = 0,
max = Math.max(tl, rh.length); counter < max;
counter++) {
if (isLiteral(rh.offset + counter)) {
if (replace != null) {
replace.append(getLiteral(rh.offset +
counter));
}
if (textIndex < tl && text.charAt(textIndex) ==
getLiteral(rh.offset + counter)) {
textIndex++;
}
else if (textIndex == 0) {
rh.offset++;
rh.length--;
counter--;
max--;
}
else if (replace == null) {
replace = new StringBuffer(max);
replace.append(text.substring(0, textIndex));
replace.append(getLiteral(rh.offset +
counter));
}
}
else if (textIndex < tl) {
if (replace != null) {
replace.append(text.charAt(textIndex));
}
textIndex++;
}
else {
// Nothing to replace it with, assume ' '
if (replace == null) {
replace = new StringBuffer(max);
if (textIndex > 0) {
replace.append(text.substring(0, textIndex));
}
}
if (replace != null) {
replace.append(' ");
}
}
}
if (replace != null) {
rh.text = replace.toString();
}
}
else if (tl > 0) {
// insert (or insert and remove)
rh.offset = getNextNonliteralIndex(rh.offset, 1);
}
else {
// remove only
rh.offset = getNextNonliteralIndex(rh.offset, -1);
}
((ExtendedReplaceHolder)rh).endOffset = rh.offset;
((ExtendedReplaceHolder)rh).endTextLength = (rh.text != null) ?
rh.text.length() : 0;
}
else {
((ExtendedReplaceHolder)rh).endOffset = rh.offset;
((ExtendedReplaceHolder)rh).endTextLength = (rh.text != null) ?
rh.text.length() : 0;
}
boolean can = super.canReplace(rh);
if (can && !getAllowsInvalid()) {
((ExtendedReplaceHolder)rh).resetFromValue(this);
}
return can;
|
public java.lang.Object | clone()Creates a copy of the DefaultFormatter.
InternationalFormatter formatter = (InternationalFormatter)super.
clone();
formatter.literalMask = null;
formatter.iterator = null;
formatter.validMask = false;
formatter.string = null;
return formatter;
|
protected javax.swing.Action[] | getActions()If getSupportsIncrement returns true, this returns
two Actions suitable for incrementing/decrementing the value.
if (getSupportsIncrement()) {
return new Action[] { new IncrementAction("increment", 1),
new IncrementAction("decrement", -1) };
}
return null;
|
java.lang.Object | getAdjustField(int start, java.util.Map attributes)Returns the field that will be adjusted by adjustValue.
return null;
|
int | getAttributeStart(java.text.AttributedCharacterIterator$Attribute id)Returns the start of the first run that contains the attribute
id . This will return -1 if the attribute
can not be found.
if (isValidMask()) {
AttributedCharacterIterator iterator = getIterator();
iterator.first();
while (iterator.current() != CharacterIterator.DONE) {
if (iterator.getAttribute(id) != null) {
return iterator.getIndex();
}
iterator.next();
}
}
return -1;
|
java.util.Map | getAttributes(int index)Returns a Set of the attribute identifiers at index .
if (isValidMask()) {
AttributedCharacterIterator iterator = getIterator();
if (index >= 0 && index <= iterator.getEndIndex()) {
iterator.setIndex(index);
return iterator.getAttributes();
}
}
return null;
|
char | getBufferedChar(int index)Returns the character from the mask that has been buffered
at index .
if (isValidMask()) {
if (string != null && index < string.length()) {
return string.charAt(index);
}
}
return (char)0;
|
private int | getFieldTypeCountTo(java.lang.Object f, int start)Returns the number of occurences of f before
the location start in the current
AttributedCharacterIterator .
AttributedCharacterIterator iterator = getIterator();
int count = 0;
if (iterator != null &&
(f instanceof AttributedCharacterIterator.Attribute)) {
AttributedCharacterIterator.Attribute field =
(AttributedCharacterIterator.Attribute)f;
int index = 0;
iterator.first();
while (iterator.getIndex() < start) {
while (iterator.getAttribute(field) == null &&
iterator.next() != CharacterIterator.DONE);
if (iterator.current() != CharacterIterator.DONE) {
iterator.setIndex(iterator.getRunLimit(field));
iterator.next();
count++;
}
else {
break;
}
}
}
return count;
|
public java.text.Format$Field[] | getFields(int offset)Returns the Format.Field constants associated with
the text at offset . If offset is not
a valid location into the current text, this will return an
empty array.
if (getAllowsInvalid()) {
// This will work if the currently edited value is valid.
updateMask();
}
Map attrs = getAttributes(offset);
if (attrs != null && attrs.size() > 0) {
ArrayList al = new ArrayList();
al.addAll(attrs.keySet());
return (Format.Field[])al.toArray(EMPTY_FIELD_ARRAY);
}
return EMPTY_FIELD_ARRAY;
|
public java.text.Format | getFormat()Returns the format that dictates the legal values that can be edited
and displayed.
return format;
|
java.text.AttributedCharacterIterator | getIterator()Returns the AttributedCharacterIterator used to
format the last value.
return iterator;
|
char | getLiteral(int index)Returns the literal character at index.
if (isValidMask() && string != null && index < string.length()) {
return string.charAt(index);
}
return (char)0;
|
int | getLiteralCountTo(int index)Returns the number of literal characters before index .
int lCount = 0;
for (int counter = 0; counter < index; counter++) {
if (isLiteral(counter)) {
lCount++;
}
}
return lCount;
|
public java.lang.Comparable | getMaximum()Returns the maximum permissible value.
return max;
|
public java.lang.Comparable | getMinimum()Returns the minimum permissible value.
return min;
|
private int | getNextNonliteralIndex(int index, int direction)Returns the index of the next non-literal character starting at
index. If index is not a literal, it will be returned.
int max = getFormattedTextField().getDocument().getLength();
while (index >= 0 && index < max) {
if (isLiteral(index)) {
index += direction;
}
else {
return index;
}
}
return (direction == -1) ? 0 : max;
|
ReplaceHolder | getReplaceHolder(javax.swing.text.DocumentFilter$FilterBypass fb, int offset, int length, java.lang.String text, javax.swing.text.AttributeSet attrs)Overriden to return an instance of ExtendedReplaceHolder .
if (replaceHolder == null) {
replaceHolder = new ExtendedReplaceHolder();
}
return super.getReplaceHolder(fb, offset, length, text, attrs);
|
boolean | getSupportsIncrement()Returns false, indicating InternationalFormatter does not allow
incrementing of the value. Subclasses that wish to support
incrementing/decrementing the value should override this and
return true. Subclasses should also override
adjustValue .
return false;
|
public void | install(javax.swing.JFormattedTextField ftf)Installs the DefaultFormatter onto a particular
JFormattedTextField .
This will invoke valueToString to convert the
current value from the JFormattedTextField to
a String. This will then install the Action s from
getActions , the DocumentFilter
returned from getDocumentFilter and the
NavigationFilter returned from
getNavigationFilter onto the
JFormattedTextField .
Subclasses will typically only need to override this if they
wish to install additional listeners on the
JFormattedTextField .
If there is a ParseException in converting the
current value to a String, this will set the text to an empty
String, and mark the JFormattedTextField as being
in an invalid state.
While this is a public method, this is typically only useful
for subclassers of JFormattedTextField .
JFormattedTextField will invoke this method at
the appropriate times when the value changes, or its internal
state changes.
super.install(ftf);
updateMaskIfNecessary();
// invoked again as the mask should now be valid.
positionCursorAtInitialLocation();
|
boolean | isLiteral(int index)Returns true if the character at index is a literal, that is
not editable.
if (isValidMask() && index < string.length()) {
return literalMask.get(index);
}
return false;
|
boolean | isLiteral(java.util.Map attributes)Returns true if attributes is null or empty.
return ((attributes == null) || attributes.size() == 0);
|
boolean | isNavigatable(int offset)Returns true if the character at offset is navigatable too. This
is implemented in terms of isLiteral , subclasses
may wish to provide different behavior.
return !isLiteral(offset);
|
boolean | isValidMask()Returns true if the current mask is valid.
return validMask;
|
boolean | isValidValue(java.lang.Object value, boolean wantsCCE)Returns true if value is between the min/max.
Comparable min = getMinimum();
try {
if (min != null && min.compareTo(value) > 0) {
return false;
}
} catch (ClassCastException cce) {
if (wantsCCE) {
throw cce;
}
return false;
}
Comparable max = getMaximum();
try {
if (max != null && max.compareTo(value) < 0) {
return false;
}
} catch (ClassCastException cce) {
if (wantsCCE) {
throw cce;
}
return false;
}
return true;
|
private void | readObject(java.io.ObjectInputStream s)Subclassed to update the internal representation of the mask after
the default read operation has completed.
s.defaultReadObject();
updateMaskIfNecessary();
|
void | replace(javax.swing.text.DocumentFilter$FilterBypass fb, int offset, int length, java.lang.String text, javax.swing.text.AttributeSet attrs)Overriden to unconditionally allow the replace if
ignoreDocumentMutate is true.
if (ignoreDocumentMutate) {
fb.replace(offset, length, text, attrs);
return;
}
super.replace(fb, offset, length, text, attrs);
|
boolean | replace(ReplaceHolder rh)When in !allowsInvalid mode the text is reset on every edit, thus
supers implementation will position the cursor at the wrong position.
As such, this invokes supers implementation and then invokes
repositionCursor to correctly reset the cursor.
int start = -1;
int direction = 1;
int literalCount = -1;
if (rh.length > 0 && (rh.text == null || rh.text.length() == 0) &&
(getFormattedTextField().getSelectionStart() != rh.offset ||
rh.length > 1)) {
direction = -1;
}
if (!getAllowsInvalid()) {
if ((rh.text == null || rh.text.length() == 0) && rh.length > 0) {
// remove
start = getFormattedTextField().getSelectionStart();
}
else {
start = rh.offset;
}
literalCount = getLiteralCountTo(start);
}
if (super.replace(rh)) {
if (start != -1) {
int end = ((ExtendedReplaceHolder)rh).endOffset;
end += ((ExtendedReplaceHolder)rh).endTextLength;
repositionCursor(literalCount, end, direction);
}
else {
start = ((ExtendedReplaceHolder)rh).endOffset;
if (direction == 1) {
start += ((ExtendedReplaceHolder)rh).endTextLength;
}
repositionCursor(start, direction);
}
return true;
}
return false;
|
private void | repositionCursor(int startLiteralCount, int end, int direction)Repositions the cursor. startLiteralCount gives
the number of literals to the start of the deleted range, end
gives the ending location to adjust from, direction gives
the direction relative to end to position the
cursor from.
int endLiteralCount = getLiteralCountTo(end);
if (endLiteralCount != end) {
end -= startLiteralCount;
for (int counter = 0; counter < end; counter++) {
if (isLiteral(counter)) {
end++;
}
}
}
repositionCursor(end, 1 /*direction*/);
|
void | resetValue(java.lang.Object value)Resets the value of the JFormattedTextField to be
value .
Document doc = getFormattedTextField().getDocument();
String string = valueToString(value);
try {
ignoreDocumentMutate = true;
doc.remove(0, doc.getLength());
doc.insertString(0, string, null);
} finally {
ignoreDocumentMutate = false;
}
updateValue(value);
|
void | selectField(java.lang.Object f, int count)Selects the fields identified by attributes .
AttributedCharacterIterator iterator = getIterator();
if (iterator != null &&
(f instanceof AttributedCharacterIterator.Attribute)) {
AttributedCharacterIterator.Attribute field =
(AttributedCharacterIterator.Attribute)f;
iterator.first();
while (iterator.current() != CharacterIterator.DONE) {
while (iterator.getAttribute(field) == null &&
iterator.next() != CharacterIterator.DONE);
if (iterator.current() != CharacterIterator.DONE) {
int limit = iterator.getRunLimit(field);
if (--count <= 0) {
getFormattedTextField().select(iterator.getIndex(),
limit);
break;
}
iterator.setIndex(limit);
iterator.next();
}
}
}
|
public void | setFormat(java.text.Format format)Sets the format that dictates the legal values that can be edited
and displayed.
this.format = format;
|
public void | setMaximum(java.lang.Comparable max)Sets the maximum permissible value. If the valueClass has
not been specified, and max is non null, the
valueClass will be set to that of the class of
max .
if (getValueClass() == null && max != null) {
setValueClass(max.getClass());
}
this.max = max;
|
public void | setMinimum(java.lang.Comparable minimum)Sets the minimum permissible value. If the valueClass has
not been specified, and minimum is non null, the
valueClass will be set to that of the class of
minimum .
if (getValueClass() == null && minimum != null) {
setValueClass(minimum.getClass());
}
min = minimum;
|
public java.lang.Object | stringToValue(java.lang.String text)Returns the Object representation of the
String text .
Object value = stringToValue(text, getFormat());
// Convert to the value class if the Value returned from the
// Format does not match.
if (value != null && getValueClass() != null &&
!getValueClass().isInstance(value)) {
value = super.stringToValue(value.toString());
}
try {
if (!isValidValue(value, true)) {
throw new ParseException("Value not within min/max range", 0);
}
} catch (ClassCastException cce) {
throw new ParseException("Class cast exception comparing values: "
+ cce, 0);
}
return value;
|
java.lang.Object | stringToValue(java.lang.String text, java.text.Format f)Invokes parseObject on f , returning
its value.
if (f == null) {
return text;
}
return f.parseObject(text);
|
void | updateMask()Updates the AttributedCharacterIterator by invoking
formatToCharacterIterator on the Format .
If this is successful,
updateMask(AttributedCharacterIterator)
is then invoked to update the internal bitmask.
if (getFormat() != null) {
Document doc = getFormattedTextField().getDocument();
validMask = false;
if (doc != null) {
try {
string = doc.getText(0, doc.getLength());
} catch (BadLocationException ble) {
string = null;
}
if (string != null) {
try {
Object value = stringToValue(string);
AttributedCharacterIterator iterator = getFormat().
formatToCharacterIterator(value);
updateMask(iterator);
}
catch (ParseException pe) {}
catch (IllegalArgumentException iae) {}
catch (NullPointerException npe) {}
}
}
}
|
private void | updateMask(java.text.AttributedCharacterIterator iterator)Updates the interal bitset from iterator . This will
set validMask to true if iterator is
non-null.
if (iterator != null) {
validMask = true;
this.iterator = iterator;
// Update the literal mask
if (literalMask == null) {
literalMask = new BitSet();
}
else {
for (int counter = literalMask.length() - 1; counter >= 0;
counter--) {
literalMask.clear(counter);
}
}
iterator.first();
while (iterator.current() != CharacterIterator.DONE) {
Map attributes = iterator.getAttributes();
boolean set = isLiteral(attributes);
int start = iterator.getIndex();
int end = iterator.getRunLimit();
while (start < end) {
if (set) {
literalMask.set(start);
}
else {
literalMask.clear(start);
}
start++;
}
iterator.setIndex(start);
}
}
|
void | updateMaskIfNecessary()Updates the AttributedCharacterIterator and bitset, if necessary.
if (!getAllowsInvalid() && (getFormat() != null)) {
if (!isValidMask()) {
updateMask();
}
else {
String newString = getFormattedTextField().getText();
if (!newString.equals(string)) {
updateMask();
}
}
}
|
void | updateValue(java.lang.Object value)Overriden to update the mask after invoking supers implementation.
super.updateValue(value);
updateMaskIfNecessary();
|
public java.lang.String | valueToString(java.lang.Object value)Returns a String representation of the Object value .
This invokes format on the current Format .
if (value == null) {
return "";
}
Format f = getFormat();
if (f == null) {
return value.toString();
}
return f.format(value);
|