Custom CellEditor Accepting Interesting Values

From: Shane Mingins (shanemingins_at_yahoo.com.clothes)
Date: 11/29/04


Date: Mon, 29 Nov 2004 16:34:26 +1300

Hi

I have a problem with a custom cell editor using a custom
JFormattedTextField.

When I tab to one of the cells in the table and just type a currency value I
find that it accepts $5 but rejects 5. $5 is the display format.

When I double click the cell it edits as expected ... accepts 5 and rejects
$5.

I read that "A cell must be double-clicked before it is edited" "In other
words, the isCellEditable() method returns a value of false when the click
count is 1, "

But I ovrride the isCellEditable() method in my editor and tabbing and
typing returned true as well as double clicking.

I have posted the code for the editor and text field below. Does anyone
have any suggestions?

Thanks
Shane

-- 
"If A is success in life, then A equals x plus y plus z. Work is x; y is
play; and z is keeping your mouth shut." -- Albert Einstein
public class CurrencyCellEditor extends DefaultCellEditor
{
    public CurrencyCellEditor(int noDecimals)
    {
        super(new CurrencyField(noDecimals));
        CurrencyField currency = (CurrencyField) getComponent();
        currency.setHorizontalAlignment(JTextField.TRAILING);
    }
    public CurrencyCellEditor()
    {
        this(2);
    }
    public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
    {
        CurrencyField currency = (CurrencyField)
super.getTableCellEditorComponent(table, value, isSelected, row, column);
        currency.setValue(value);
        return currency;
    }
    public Object getCellEditorValue()
    {
        return ((CurrencyField) getComponent()).getBigDecimalValue();
    }
    public boolean stopCellEditing()
    {
        CurrencyField currency = (CurrencyField) getComponent();
        if (currency.isEditValid())
        {
            try
            {
                currency.commitEdit();
            }
            catch (ParseException e)
            {
                currency.setValue(currency.getValue());
            }
        }
        return super.stopCellEditing();
    }
}
public class CurrencyField extends JFormattedTextField
{
    /**
     * A formatter to check the format of currency fields.
     * It provides additional functionality by adding a DocumentFilter.
     *
     * @author Glenn Colman
     */
    private static class CurrencyFormatter extends NumberFormatter
    {
        private DocumentFilter documentFilter;
        public CurrencyFormatter(int noDecimals)
        {
            super(getCurrencyEditFormat(noDecimals));
        }
        public DocumentFilter getDocumentFilter()
        {
            if (documentFilter == null)
            {
                documentFilter = new BasicDocumentFilter(new char[]{'0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '.', '$', '+', '-'});
            }
            return documentFilter;
        }
    }
    /**
     * Get the appropriate NumberFormat for editing this component.
     *
     * @return
     */
    private static NumberFormat getCurrencyEditFormat(int noDecimals)
    {
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMinimumFractionDigits(noDecimals);
        nf.setMaximumFractionDigits(noDecimals);
        return nf;
    }
    /**
     * Create a CurrencyField that will use a CurrencyFormatter and a
BasicInputVerifier.
     */
    public CurrencyField(int noDecimals)
    {
        super(new DefaultFormatterFactory(new
NumberFormatter(NumberFormatUtils.getCurrencyDisplayFormat(noDecimals)),
                new
NumberFormatter(NumberFormatUtils.getCurrencyDisplayFormat(noDecimals)),
                new CurrencyFormatter(noDecimals)));
        super.setInputVerifier(new BasicInputVerifier());
    }
    // default to 2dp
    public CurrencyField()
    {
        this(2);
    }
    /**
     * Returns value as a BigDecimal
     *
     * @return the last valid value as a BigDecimal
     * @see BigDecimal
     * @see javax.swing.JFormattedTextField
     */
    public BigDecimal getBigDecimalValue()
    {
        return ((getValue() == null) ? null : new BigDecimal(((Number)
getValue()).doubleValue()));
    }
}