0

I've tried many things to display a comma instead of a point in my JTable in "German"-style. In my JTable-Class I wrote a methode for looping a passed ResultSet for filling a DefaultTableModel and returning the Model or the JTable directly.

If I cast a BigDecimal to a String for replacing a point with a comma, the Result will be displayed correctly in my JTable - but then my Sorting-Sequence is not correct because the values will be sorted as a String instead of a BigDecimal...

The other Solution would be to sort directly via SQL-Statement and to dynamically change the sorting-sequence when I click on the row-header - but this is for me not the best solution because the contents of my Table are generated by executing a lot of Queries which take a lot of time.

I tried to set the locale of my JTable but nothing really worked.

Anybody an idea, how to display in german format?

Thanks a lot!

Here is my Class:

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;


public class MyJTable extends JTable {  

private static final long serialVersionUID = 1L;    

public MyJTable(){      
   this.setLocale(Locale.GERMANY);  
}

public MyJTable(ResultSet rs) throws SQLException{        
            DefaultTableModel model = this.getTableModel(rs);
            this.setModel(model);
            RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
            this.setRowSorter(sorter);
            this.setLocale(Locale.GERMANY);
}

public DefaultTableModel getTableModel(ResultSet rs) throws SQLException{

    ResultSetMetaData metaData = rs.getMetaData();
    // names of columns
    Vector<String> columnNames = new Vector<String>();
    int columnCount = metaData.getColumnCount();
    for (int column = 1; column <= columnCount; column++) {
        columnNames.add(metaData.getColumnName(column));
    }
    // data of the table
    Vector<Vector<Object>> data = new Vector<Vector<Object>>();
    String bigdecimal=null;
    Object obigdecimal;
    while (rs.next()) {
        Vector<Object> vector = new Vector<Object>();
        for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {

            if     (metaData.getColumnClassName(columnIndex).equals("java.math.BigDecimal")){
                bigdecimal=rs.getString(columnIndex);
                if (bigdecimal!=null){
                bigdecimal=bigdecimal.replace(".",",");
                obigdecimal=bigdecimal;
                vector.add(obigdecimal);
                }               
            }
            else
            {
            vector.add(rs.getObject(columnIndex));
            }               
          }
        data.add(vector);
}

    return new DefaultTableModel(data, columnNames){

        private static final long serialVersionUID = 1L;

            public Class getColumnClass(int column) {
                Class returnValue=Object.class;
                try{
                if ((column >= 0) && (column < getColumnCount())) {
                  returnValue = getValueAt(0, column).getClass();
                } else {
                  returnValue = Object.class;
                }                     
                }
                catch(Exception e){}                    
                return returnValue;
              }
            };      
    }   
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
BlackFlag
  • 150
  • 8
  • 3
    Have you thought of using a TableCellRender. With a Render you would only affect display of the data and not the data itself so It woul not affect sorting. Most example show it being used for Checkboxes, Combos but they can be used to reformat the text display.See http://docs.oracle.com/javase/tutorial/uiswing/components/table.html – Bruce Martin Feb 09 '15 at 10:42

2 Answers2

1

Replace point with comma in a JTable causes a wrong sorting-sequence

A little part of the problem is you are mixing up the data itself about how should it be displayed or rendered.

However the main problem IMHO is you don't override getColumnClass(int columnIndex) in your table model: I'd never trust in asking the model for the first row cells' classes. What if getValueAt(0,1) returns null? Answer: you'll get a NullPointerException at getValueAt(0,1).getClass() call.

Now given the context in your question you can't provide an appropriate TableCellRenderer because you don't know what class will the result set return beforehand. However you can rely on the default behavior described in Concepts: Editor and Renderers and override getColumnClass(...) method to return a correct class using the ResultSetMetaData as follows:

public TableModel getTableModel(ResultSet resultSet) throws SQLException {    
    ResultSetMetaData metaData = resultSet.getMetaData();        

    int columnCount = metaData.getColumnCount(); // columns number
    String[] columnNames = new String[columnCount];
    final Class[] columnClasses = new Class[columnCount];

    for (int i = 1; i <= columnCount; i++) {
        columnNames[i-1] = metaData.getColumnName(i); // fill columns names
        try {
            columnClasses[i-1] = Class.forName(metaData.getColumnClassName(i)); // fill column classes
        } catch (ClassNotFoundException ex) {
            // Log the exception here
        }
    }

    resultSet.last();
    int rowCount = resultSet.getRow(); // get rows number
    resultSet.beforeFirst();

    Object[][] data = new Object[rowCount][columnCount];
    int currentRow = 0;
    while (resultSet.next()) {
        for (int currentColumn = 1; currentColumn <= columnCount; currentColumn++) {
            data[currentRow][currentColumn - 1] = resultSet.getObject(currentColumn); // fill data set
         }
         currentRow++;
    }

    TableModel model = new DefaultTableModel(data, columnNames) {
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return columnClasses[columnIndex];
        }
    }
    return model;    
}

Note: the use of Object[] instead of Vector is just because I had the code somewhere else and I'm too lazy to modify it.

Community
  • 1
  • 1
dic19
  • 17,821
  • 6
  • 40
  • 69
0

but then my Sorting-Sequence is not correct because the values will be sorted as a String instead of a BigDecimal...

Don't store a String in the TableModel. Store the BigDecimal.

If I cast a BigDecimal to a String for replacing a point with a comma,

Formatting the data is the job of the renderer. Check out Table Format Renderers for a simple example of how to override the setValue(...) method of the renderer.

You will also need to override the getColumnClass(...) method to return BigDecimal so the appropriate sort can be done.

camickr
  • 321,443
  • 19
  • 166
  • 288