Формат номера редактора ячеек JTable

Мне нужно показать числа в jTable с точными двумя десятичными знаками. Для этого я создал собственный редактор ячеек:

public class NumberCellEditor extends DefaultCellEditor {
    public NumberCellEditor(){
        super(new JFormattedTextField());
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        JFormattedTextField editor = (JFormattedTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);

        if (value!=null){
            DecimalFormat numberFormat = new DecimalFormat("#,##0.00;(#,##0.00)");
            editor.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(numberFormat)));
            Number num = (Number) value;  
            String text = numberFormat.format(num);
            editor.setHorizontalAlignment(SwingConstants.RIGHT);
            editor.setText(text);
        }
        return editor;
    }
}

Этот редактор ячеек идеально подходит для английского языка, где в качестве десятичной точки используется точка. Но в немецкой локали он не принимает значения с запятой в качестве десятичной точки. Пожалуйста, дайте мне знать, где есть проблема в моем коде. Заранее спасибо.

РЕДАКТИРОВАТЬ: Вот как я заработал:

public class NumberCellEditor extends DefaultCellEditor {
public NumberCellEditor(){
    super(new JFormattedTextField());
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    JFormattedTextField editor = (JFormattedTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);

    if (value instanceof Number){
        Locale myLocale = Locale.getDefault(); 

        NumberFormat numberFormatB = NumberFormat.getInstance(myLocale);
        numberFormatB.setMaximumFractionDigits(2);
        numberFormatB.setMinimumFractionDigits(2);
        numberFormatB.setMinimumIntegerDigits(1);

        editor.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
                        new NumberFormatter(numberFormatB)));

        editor.setHorizontalAlignment(SwingConstants.RIGHT);
        editor.setValue(value);
    }
    return editor;
}

@Override
public boolean stopCellEditing() {
    try {
        // try to get the value
        this.getCellEditorValue();
        return super.stopCellEditing();
    } catch (Exception ex) {
        return false;
    }

}

@Override
public Object getCellEditorValue() {
    // get content of textField
    String str = (String) super.getCellEditorValue();
    if (str == null) {
        return null;
    }

    if (str.length() == 0) {
        return null;
    }

    // try to parse a number
    try {
        ParsePosition pos = new ParsePosition(0);
        Number n = NumberFormat.getInstance().parse(str, pos);
        if (pos.getIndex() != str.length()) {
            throw new ParseException(
                    "parsing incomplete", pos.getIndex());
        }

        // return an instance of column class
        return new Float(n.floatValue());

    } catch (ParseException pex) {
        throw new RuntimeException(pex);
    }
}
}

person Khalid Amin    schedule 02.07.2011    source источник
comment
Я уже проголосовал за ваш вопрос, но хотел бы сделать это снова. Спасибо, что опубликовали это!   -  person Hovercraft Full Of Eels    schedule 04.07.2011


Ответы (4)


Используйте локаль в своих интересах:

  //Locale myLocale = Locale.GERMANY;  //... or better, the current Locale

  Locale myLocale = Locale.getDefault(); // better still

  NumberFormat numberFormatB = NumberFormat.getInstance(myLocale);
  numberFormatB.setMaximumFractionDigits(2);
  numberFormatB.setMinimumFractionDigits(2);
  numberFormatB.setMinimumIntegerDigits(1);

  edit.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
                    new NumberFormatter(numberFormatB)));
person Hovercraft Full Of Eels    schedule 02.07.2011
comment
@StanislavL вам когда-то нужно было установить Локаль для JComponents такой же Локаль, как вернуть все сегодняшние родные ОС по умолчанию? - person mKorbel; 02.07.2011
comment
Я изменил свой код в соответствии с приведенным выше блоком, но я все еще сталкиваюсь с проблемой. При двойном щелчке поле редактирования правильно отображает значение в формате с учетом локали (оно показывает запятую как десятичную точку для немецкой локали), но оно не принимает отредактированное значение с запятой в качестве десятичной точки (когда просто показывает старое значение, когда мы попробуйте отредактировать его на что-то, что содержит запятую в качестве точки) - person Khalid Amin; 03.07.2011
comment
@Statue: рассмотрите возможность создания SSCCE, небольшой компилируемой и исполняемой программы, которая не требует внешних ресурсов (например, изображений или базы данных). ) и который демонстрирует вашу проблему, а затем опубликовать его как редактирование вашего вопроса. - person Hovercraft Full Of Eels; 03.07.2011
comment
Мне удалось заставить его работать отлично, переопределив методы getCellEditorValue и stopEditing из DefaultCellEditor. - person Khalid Amin; 03.07.2011
comment
@Statue: Поздравляю!! Я хотел бы увидеть ваш успешный код редактора ячеек. Вы можете опубликовать это для нас? - person Hovercraft Full Of Eels; 03.07.2011
comment
Конечно, я должен разместить код здесь, в комментариях? Или есть более подходящее место для публикации? - person Khalid Amin; 04.07.2011
comment
@Statue: вы не можете оставлять комментарии. Вместо этого опубликуйте его как редактирование исходного сообщения. - person Hovercraft Full Of Eels; 04.07.2011

Например

import java.text.NumberFormat;
import java.math.RoundingMode;
import javax.swing.table.DefaultTableCellRenderer;


public class SubstDouble2DecimalRenderer extends DefaultTableCellRenderer {

    private static final long serialVersionUID = 1L;
    private int precision = 0;
    private Number numberValue;
    private NumberFormat nf;

    public SubstDouble2DecimalRenderer(int p_precision) {
        super();
        setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        precision = p_precision;
        nf = NumberFormat.getNumberInstance();
        nf.setMinimumFractionDigits(p_precision);  
        nf.setMaximumFractionDigits(p_precision);
        nf.setRoundingMode(RoundingMode.HALF_UP);  
    }

    public SubstDouble2DecimalRenderer() {
        super();
        setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        nf = NumberFormat.getNumberInstance();
        nf.setMinimumFractionDigits(2);
        nf.setMaximumFractionDigits(2);
        nf.setRoundingMode(RoundingMode.HALF_UP);
    }

    @Override
    public void setValue(Object value) {
        if ((value != null) && (value instanceof Number)) {
            numberValue = (Number) value;
            value = nf.format(numberValue.doubleValue());
        }
        super.setValue(value);
    }
}
person mKorbel    schedule 02.07.2011

Пытаться

DecimalFormat numberFormat = new DecimalFormat("\\d*([\\.,\\,]\\d{0,2})?");
person Eng.Fouad    schedule 02.07.2011

Просто замените #,###,###,##0.00 на #.###.###.##0,00

person user2316705    schedule 22.11.2013