Komma in Zelle für Double-Werte eingeben


#1

Ich möchte in eine JTable Zahlen mit Komma als Dezimaltrenner eingeben können.
Aktuell wird die Zelle nach der Eingabe rot umrandet, wenn ich ein Komma als Dezimaltrenner eingebe, es wird nur ein Punkt akzeptiert.

Das gleiche Problem hatte ich auch bei der Ausgabe solcher Zahlen, was ich aber mit einem eigenen Renderer lösen konnte.

Ich habe bereits mehrere Suchergebnisse aus Suchmaschinen ausprobiert, die aber bei mir nicht funktionieren wollten, oder nicht zu meinem Problem gepasst haben. Die betreffenden Zellen akzeptierten weiterhin keine “Kommazahl”.
Im Model erfolgt dann noch eine Berechnung.

Kann mir da mal jemand zeigen, wie das richtig geht?


#2

Schon lange her, dass ich das letzte mal was mit JTables gearbeitet habe, aber ich denke mit einem CellEditor bist du da doch normal ganz gut unterwegs. So mal auf die schnelle:


try {
    formatter = new MaskFormatter("#,##");
} catch (ParseException e) {
    e.printStackTrace();
}

JFormattedTextField formattedTextField = new JFormattedTextField(formatter);
table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(formattedTextField));

Könnte sowas die Richtung passen? Wenn nicht vielleicht mehr Infos und/oder Code.


#3

Danke dir.

Ich habe das nun mal so eingebaut. Funktioniert leider auch nicht, wie gewünscht.
Man kann das Editieren nicht beenden. Dann muss da wohl noch irgendwo ein stopCellEdit hinein.
Und das JFormattedTextField verringert die Größe der Zelle, so dass man nicht mehr lesen kann, was eingegeben wurde.

Mein erster selbst geschriebener Editor sieht nun so aus:


    private JFormattedTextField component;

    public NumberCellEditor() {
        MaskFormatter formatter = null;

        try {
            formatter = new MaskFormatter("#,##");
        }
        catch (ParseException e) {
            e.printStackTrace();
        }
        component = new JFormattedTextField(formatter);
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowIndex, int colIndex) {
        component.setText(value == null ? null : value.toString());
        return component;
    }

    @Override
    public Object getCellEditorValue() {
        return component.getText();
    }
}

*** Edit ***

Das Problem, dass das JFormattedTextField die Zelle so klein erscheinen lässt, dass man beim Editieren nichts mehr lesen kann, habe ich nun behoben, indem ich den Rand des Textfeldes mit [inline]component.setBorder(null);[/inline] entfernt habe.


#4

ist das noch aktuell?
ein komplettes Testprogramm und genaue Anleitungen würden helfen,
Ende bei Enter gewünscht aber nicht funktionierend, bei Mausklick woanders oder oder?
und vorher ging es?

zur Sicherheit allgemein ergänzt:


#5

Ein komplettes Testprogramm ist schwierig, weil es aus vielen Fragmenten besteht, die ich im Netz gefunden habe. Das Ganze ist inzwischen recht umfangreich.

Ich habe ein weiteres Suchmaschinen-Fundstück ausprobiert. Nach einigen kleinen Anpassungen funktioniert nun fast alles.
Der aktuelle Code des CellEditors sieht so aus:


    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);
        editor.setFont(table.getFont());
        editor.setBorder(null);

        if (value instanceof Number) {
            NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
            numberFormat.setMaximumFractionDigits(1);
            numberFormat.setMinimumFractionDigits(0);
            numberFormat.setMinimumIntegerDigits(1);

            editor.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(numberFormat)));

            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 || str.trim().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 n;

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