0

I have a Simple JTable holding Integers in the first column and Strings in the Second. I would like to be able to sort each Column.

My Renderer:

    package gui.table;

import gui.DaimlerColor;

import java.awt.Component;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

@SuppressWarnings("serial")
public class StandardCellRenderer extends DefaultTableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {

        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        c.setBackground((isSelected ?  DaimlerColor.LIGHT_BLUE : (row % 2 == 1 ? DaimlerColor.DARK_WHITE : DaimlerColor.WHITE)));
        if(isSelected){
            c.setBackground(DaimlerColor.LIGHT_BLUE);
        }
        return c;   
    }

}

My TableModel:

package gui.table;

import java.util.List;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import org.jdom2.Element;

import reporting.FailureClassificationCatalogue;

@SuppressWarnings("serial")
public class ReportTableModel extends DefaultTableModel {

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    public ReportTableModel(List<Element> reports) {

        super(createDataVector(reports), createColumnNames());
    }

    private static Vector<Vector<Object>> createDataVector(List<Element> reports) {

        Vector<Vector<Object>> data = new  Vector<Vector<Object>>();
        for (int i = 0; i < reports.size(); i++) {
            Vector<Object> row = new Vector<Object>();
            if(reports.get(i).getName().equals("Default")){
                row.add("-");
            }
            else{
            row.add(Integer.valueOf(i+1));
            }
            String title = reports.get(i).getAttributeValue("type");
            try{
                title = FailureClassificationCatalogue.valueOf(title).getName();
            }catch(IllegalArgumentException iae){

            }catch(NullPointerException npe){

            }
            row.add(title);
            data.add(row);
       }
       return data;
    }

    @Override
    public Class<?> getColumnClass(int colNum) {
        switch (colNum) {
            case 0:
                return Integer.class;
            case 1:
                return String.class;
            default:
                return String.class;
        }
    } 

    private static Vector<String> createColumnNames() {
        Vector<String> columns = new Vector<String>(); 
        columns.add("Number");
        columns.add("Error Type");
        return columns;
    }

    /**
     * overridden to ignore null values
     */
    @Override
    public void setValueAt(Object value, int row, int col) {
        if (value == null) {
            return;
        }
        // delegate to the parent method
        super.setValueAt(value, row, col);
    }
}

If I don´t implement the getColumnClass then the renderer works fine but the Integers are sorted as Strings. As soon as I implement the method the renderer doesn´t work properly (background is only set in one column) but the Integers are sorted correctly. How can I resolve this?

My Code to set the renderer and sorter:

reporttable = new JTable();
        reporttable.setName("report");
        reporttable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        reporttable.setRowHeight(40);
        reporttable.addMouseListener(tgc.mouseListener);
        reporttable.setDefaultRenderer( Object.class, new StandardCellRenderer());
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>();
            reporttable.setRowSorter(sorter);
            sorter.setModel(reportModel);

Any ideas? Thanks.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Hans En
  • 906
  • 5
  • 15
  • 32

1 Answers1

2

Absent an sscce, two several things stand out:

  1. The call to setDefaultRenderer() should specify the data type to which it applies, e.g. String.class or Integer.class. Alternatively, override the table's prepareRenderer() to consider all cells, as shown here.

    reporttable.setDefaultRenderer(Integer.class, new StandardCellRenderer());
    
  2. Your TableRowSorter constructor "Creates a TableRowSorter with an empty model." Instead, pass your TableModel to the constructor or use setAutoCreateRowSorter(true).

    reporttable.setAutoCreateRowSorter(true);
    
  3. "When using a sorter, always remember to translate cell coordinates," as discussed here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • where should the prepareRenderer() method be overwritten? DefaultCellRenderer does not have this method. – Hans En Aug 15 '13 at 08:54
  • @Hans En few times is touched convertXxxToXxx in questions here, tagged by RowSorter/RowFilter (sorting/filtering) for prepareRenderer or TableCellRenderer too, – mKorbel Aug 15 '13 at 09:32