001: /**
002: * L2FProd.com Common Components 7.3 License.
003: *
004: * Copyright 2005-2007 L2FProd.com
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package com.l2fprod.common.beans.editor;
018:
019: import com.l2fprod.common.swing.LookAndFeelTweaks;
020: import com.l2fprod.common.util.converter.ConverterRegistry;
021: import com.l2fprod.common.util.converter.NumberConverters;
022:
023: import java.text.NumberFormat;
024:
025: import javax.swing.JFormattedTextField;
026: import javax.swing.JTextField;
027: import javax.swing.UIManager;
028: import javax.swing.text.DefaultFormatterFactory;
029: import javax.swing.text.NumberFormatter;
030:
031: /**
032: * Base editor for numbers. <br>
033: */
034: public class NumberPropertyEditor extends AbstractPropertyEditor {
035:
036: private final Class type;
037: private Object lastGoodValue;
038:
039: public NumberPropertyEditor(Class type) {
040: if (!Number.class.isAssignableFrom(type)) {
041: throw new IllegalArgumentException(
042: "type must be a subclass of Number");
043: }
044:
045: editor = new JFormattedTextField();
046: this .type = type;
047: ((JFormattedTextField) editor).setValue(getDefaultValue());
048: ((JFormattedTextField) editor)
049: .setBorder(LookAndFeelTweaks.EMPTY_BORDER);
050:
051: // use a custom formatter to have numbers with up to 64 decimals
052: NumberFormat format = NumberConverters.getDefaultFormat();
053:
054: ((JFormattedTextField) editor)
055: .setFormatterFactory(new DefaultFormatterFactory(
056: new NumberFormatter(format)));
057: }
058:
059: public Object getValue() {
060: String text = ((JTextField) editor).getText();
061: if (text == null || text.trim().length() == 0) {
062: return getDefaultValue();
063: }
064:
065: // allow comma or colon
066: text = text.replace(',', '.');
067:
068: // collect all numbers from this textfield
069: StringBuffer number = new StringBuffer();
070: number.ensureCapacity(text.length());
071: for (int i = 0, c = text.length(); i < c; i++) {
072: char character = text.charAt(i);
073: if ('.' == character || '-' == character
074: || (Double.class.equals(type) && 'E' == character)
075: || (Float.class.equals(type) && 'E' == character)
076: || Character.isDigit(character)) {
077: number.append(character);
078: } else if (' ' == character) {
079: continue;
080: } else {
081: break;
082: }
083: }
084:
085: try {
086: lastGoodValue = ConverterRegistry.instance().convert(type,
087: number.toString());
088: } catch (Exception e) {
089: UIManager.getLookAndFeel().provideErrorFeedback(editor);
090: }
091:
092: return lastGoodValue;
093: }
094:
095: public void setValue(Object value) {
096: if (value instanceof Number) {
097: ((JFormattedTextField) editor).setText(value.toString());
098: } else {
099: ((JFormattedTextField) editor).setValue(getDefaultValue());
100: }
101: lastGoodValue = value;
102: }
103:
104: private Object getDefaultValue() {
105: try {
106: return type.getConstructor(new Class[] { String.class })
107: .newInstance(new Object[] { "0" });
108: } catch (Exception e) {
109: // will not happen
110: throw new RuntimeException(e);
111: }
112: }
113:
114: }
|