4

I have to make one of my columns in JTable which is double type to get only numbers and to round all with precision 2. Not only to show them with this precision but instead to write the number into data with precision 2. In fact if I write 2.456 it should write 2.46 in the cell and in the data. How is the best way to do this ? With custom cell renderer or with custom cell editor ? I have this code but its dont change the data it only shows correct data on the cell

public class DoubleCellRenderer extends DefaultTableCellRenderer {

int precision = 0;
Number numberValue;
NumberFormat nf;

public DoubleCellRenderer(int aPrecision) {
    super();
    precision = aPrecision;
    setHorizontalAlignment(SwingConstants.RIGHT);
    nf = NumberFormat.getNumberInstance();
    nf.setMinimumFractionDigits(aPrecision);
    nf.setMaximumFractionDigits(aPrecision);
}

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


}
user1761818
  • 365
  • 1
  • 7
  • 14
  • JTable has two states, Renderer and Editor, Renderer is about formating value stores in XxxTableModel, nothing else, Editor is about add, motify, remove value stores in XxxModel, in the moment that CellEditor doesn't exists, then add, motify, remove value is stored in XxxTableModel – mKorbel Nov 09 '12 at 07:34

3 Answers3

3

You should use both.

CellRenderer: how the data is displayed (what you are going to show)

CellEditor: how the data is edited (eventually you can choose what value to set in your model)

In both case you can choose the precision. See more info here: http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender

Note: I would recommend to rather override getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) than setValue(Object value)

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • but I want to display data in different way of its editing. So isnt it better to use only editor? – user1761818 Nov 08 '12 at 22:12
  • @user1761818 Editor is only the way you edit the data. Only one cell can be edited at a time, so all others are "rendered" with the TableCellRender. – Guillaume Polet Nov 08 '12 at 22:14
  • but I can fill only one cell in a time so its good. I just want when I enter double number wit more of 2 precision it to be saved like number with precision two. What to do? editor or render and which method to override – user1761818 Nov 08 '12 at 22:19
  • @user1761818 You are mixing two different concepts. Those two classes are meant for different purposes. It is not a question of choice (do I take one or the other?). One is reponsible on how to display the data (for example your data is `2.123456` and you want to only show `2.12`), the other is reponsible on how the data can be edited (for example the user types `2.569874` and you will only store `2.57`) – Guillaume Polet Nov 09 '12 at 06:21
3

If I understood your question correctly, you want to store the doubles with limited precision in your model, even when the user fills in a value with more digits.

In that case you only need a custom editor to round the value before storing it in your model. Override/adjust the getCellEditorValue() method to perform the necessary rounding on the input value

Robin
  • 36,233
  • 5
  • 47
  • 99
1

I agree with Guillaume use both. Here is a link with a good implementation for the renderer that uses the getTableCellRendererComponent override mentioned in the other answer.

http://helpdesk.objects.com.au/java/how-to-control-decimal-places-displayed-in-jtable-column

I modified it slightly to enforce 3 digits only in rounding. Also added a check to ensure that the data type is double

public static class DecimalFormatRenderer extends DefaultTableCellRenderer {
    private static final long serialVersionUID = 1L;
    private static final DecimalFormat formatter = new DecimalFormat( "#.###" );

    public DecimalFormatRenderer(){
        super();
        formatter.setMinimumFractionDigits(3);
    }

    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    // First format the cell value as required

        if(value instanceof Double){
            value = formatter.format((Number)value);
        }

        return super.getTableCellRendererComponent(
            table, value, isSelected, hasFocus, row, column );
    } 
}
pbible
  • 1,259
  • 1
  • 18
  • 34