1

Say I have following columns in my Jtable:

{"Item", "Price"}

I want format the price column to "0.00" format. But if user enter an illegal string, then keep the original value of the cell. ex, when the price is "1.23", but when user want to enter "abc", then the cell should still be "1.23"

How could I do this?

Thanks

Riduidel
  • 22,052
  • 14
  • 85
  • 185
Leon
  • 8,151
  • 11
  • 45
  • 51

4 Answers4

2

Let's split your big problemn into smaller ones.

First, you want to have items of your Price column to be displayed according to a specified format, which you can achieve using a TableCellRenderer (which, when rendering numbers, will use a NumberFormat to display the correct number of decimals). As your table has only two columns of different types, the simplest solution is to use JTable#setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer). This way, your numbers will always be displayed using the correct number of decimals.

Second, for your edition issue, the same solution can be rather elegant : call JTable#setDefaultEditor(java.lang.Class, javax.swing.table.TableCellEditor) and set as editor a component one that will, before commiting change to your table model, ensure the new value is a valid number (valid of course according to your rules).

Riduidel
  • 22,052
  • 14
  • 85
  • 185
  • I am not sure if there is any solution that could avoid using both DefaultRenderer and Default Editor, but this solution works. Thank you and all other people helped me – Leon Jan 28 '11 at 21:05
2

A JTable supports this by default. The table will choose the renderer/editor based on the data stored in each column. So all you need to do is override the getColumnClass(...) method to return Double.class. Then when you edit a cell the editor will make sure the value entered is a valid number.

If you want more control over how the number is formatted then you can use Table Format Renderer.

camickr
  • 321,443
  • 19
  • 166
  • 288
1

JFormattedTextField works the way you describe so just create a new CellEditor that extends JFormattedTextField.

jzd
  • 23,473
  • 9
  • 54
  • 76
0

Put the formatting command into a try/catch block. If the operation fails with an NumberFormatException, cancel the edit.

Using your original code, make a few minor changes:

public void setValue(Object value) {
   NumberFormat formatter = new DecimalFormat("0.00");
   String s = null;
   try {
      s = formatter.format(Integer.parseInt((String)value));
      if (null != s) setText(s);
   } catch (NumberFormatException ex) {
      // what could I do here?
      // You could display a warning JOptionPane and/or output to System.out
   }
}
D.N.
  • 2,160
  • 18
  • 26
  • could you give more detailed answer? I extended the DefaultTableCellRenderer and rewrote the setText method: – Leon Jan 28 '11 at 15:32
  • Sure thing. First post the code you are using to format the cell in your question, and I will make some suggestions to the change. Don't worry, it's pretty straight forward. – D.N. Jan 28 '11 at 15:34
  • class DateRenderer extends DefaultTableCellRenderer { public DateRenderer() { super(); } public void setValue(Object value) { NumberFormat formatter = new DecimalFormat("0.00"); String s = null; try { s = formatter.format(Integer.parseInt((String)value)); } catch (Exception ex ) { // what could I do here? } if (null != s) setText(s); } } } – Leon Jan 28 '11 at 15:35
  • Best thing to do is edit your original question. Add your code, select it, then click on the curly braces button ("{ }"). It indents the code by 4 spaces, which is what the editor uses to determine you are trying to show code. – D.N. Jan 28 '11 at 15:40
  • with the code you suggested, when the it can't format the input, it will not go back to original value of that cell – Leon Jan 28 '11 at 15:55
  • You could grab the current value of the cell, store it, attempt to set the formatted cell value, and set the cell value to the stored value if it fails. However, the more appropriate answer would be to use a `TableCellEditor` as others have suggested. – D.N. Jan 28 '11 at 16:05