javaswingjtabletablecellrenderer

Overriding JTable's DefaultTableCellRenderer to center all the cells in a JTable


I've got a problem I can't get rid of.

Just so you know, I'm fairly new to using JTables, so the answer might be simple, but I can't find a solution :/

So, I've got a JTable using an AbstractTableModel, which overrides the

    public Class<?> getColumnClass(int columnIndex_p) 

method, to tell the type of each column to be displayed. One of them is a Boolean.

When I create a simple JTable, using

    table_l = new JTable(new MyTableModel());

everything is fine, and Boolean values are correctly displayed using checkboxes (on/off).

Now, I'd like to center the text on each cell (and, possibly more options later).

So I define a new DefaultTableCellRenderer for each column, like this :

    DefaultTableCellRenderer cellRenderer_l = new DefaultTableCellRenderer() {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          // delegate the rendering part to the default renderer (am i right ???)
          Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
          return comp;
        }
    }

and then I just set the horizontal alignment of this CellRender with :

    cellRenderer_l.setHorizontalAlignment(JLabel.CENTER);

Then I install this new CellRenderer on each column of the JTable :

    for (int i = 0; i < table_l.getColumnCount(); ++i) {
        table_l.getColumnModel().getColumn(i).setCellRenderer(cellRenderer_l);
    }

But, with the new CellRenderer, the displayed JTable isn't using the getColumnClass() method of my TableModel anymore, and thus just display "true/false" String on Boolean values.

I don't know how to get it to still use the getColumnClass() as before.

If someone has the answer... Thank you

EDIT: thanks for all the clarifications you made. In fact, my real question was : "how to affect all DefaultRenderer of a JTable to make them center their result in the JTable's cells"


Solution

  • For applying the same visual decoration to all rendering components (if that's what you really want, be careful, it might have an usability penalty!) you can override the JTable's preparedRenderer method:

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(...);
        if (comp instanceof JLabel) {
            ((JLabel) comp).setHorizontalAlignment(...);
        }
        return comp;
    }
    

    BTW: this approach is violating the rule to not subclass JSomething for application needs. You might consider using SwingX which formally supports visually decorating rendering components. So instead of subclassing, you would register a Highlighter with the table:

    JXTable table = ...
    table.addHighlighter(new AlignmentHighlighter(CENTER), HighlightPredicate.ALWAYS);