3

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"

adrien.pain
  • 443
  • 2
  • 11
  • 18
  • Check this. You may get a clue. Here I suggested to add radio buttons in the table column. - http://stackoverflow.com/questions/9117716/insert-radiobuttons-in-jtable-netbeans/9117895#9117895 – Ravindra Gullapalli Feb 08 '13 at 09:57
  • Thanks for the quick reply. However, isn't there any simpler solution ? All I want to do, in fact, is defining a new DefaultCellRenderer which does exactly like the default used by the JTable, but just center text in cells – adrien.pain Feb 08 '13 at 10:13
  • if per-column renderers are set, those are used irrespective of the per-class defaults (see the JTable source for the exact lookup logic) – kleopatra Feb 08 '13 at 10:54
  • @kleopatra thanks for your reply, I wasn't aware of that. I then tried to redefine DefaultCellRenderer for Object, Number and Boolean, and call setHorizontalAlignment(CENTER) of those new DefaultCellRenderer, but with no success – adrien.pain Feb 08 '13 at 11:12

2 Answers2

5

The default cell renderer already does this for values of type Boolean.class, as shown here. If this is not sufficient, please edit your question to include an sscce that exhibits any problems you encounter.

Addendum: If you need to further customize a DefaultTableCellRenderer, specify the renderer for the applicable type using setDefaultRenderer(), as shown here.

table.setDefaultRenderer(Boolean.class, yourCellRenderer); 

image

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • yep, I know the default renderer handles Boolean as checkboxes. All I want to do, in fact, is defining a new DefaultCellRenderer which does exactly like the default used by the JTable, but just center text in cells – adrien.pain Feb 08 '13 at 10:09
  • I think you want to apply the renderer by class, rather than by column; more above. – trashgod Feb 08 '13 at 10:17
  • thanks for the clue. I could define many renderers, one for each possible type in my JTables, and then customize them. But I would like to "tell" the JTable : "just use your default renderer, but center the result in the cell". Isn't there a simple way to do that ? :( – adrien.pain Feb 08 '13 at 10:25
  • I think `CENTER` is the default for both `DefaultTableCellRenderer` and `DefaultCellEditor(JCheckBox)`. Are you seeing somethting different? – trashgod Feb 08 '13 at 10:39
  • CENTER is the default for JCheckBox, but String are left-aligned, while Numbers are right-aligned. I want my JTable to center the content of every cell, without regarding its type – adrien.pain Feb 08 '13 at 10:43
  • 1
    But, seeing your replies and documentation, I'm starting thinking that I will have to replace the renderer for all the possible Types in my JTable I want to be centered. Like installing new Renderers for String, new Renderers for Number etc... – adrien.pain Feb 08 '13 at 10:45
  • 1
    nitpicking: the default renderer for booleans is _not_ of type DefaultTableCellRenderer and Center is _not_ the default alignment for DefaultTableCellRenderer:-) +1 for what you really mean – kleopatra Feb 08 '13 at 10:46
  • @adrien.pain I doubt that you (read: your users) _really_ want numbers to be centered :-) Anyway, you probably want to edit your question and add the clarification there – kleopatra Feb 08 '13 at 10:49
  • 1
    @kleopatra highlights a crucial distinction: `JTable` default renderers also implement `UIResource` and invoke `setHorizontalAlignment()` as [documented](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender). If you _really_ want to change the default alignment, you can usually replace the default renderer with one derived from `DefaultTableCellRenderer`. – trashgod Feb 08 '13 at 11:02
  • @trashgod yep, I want to choose the default alignment, replacing the default renderer. But how to simply do it please ? – adrien.pain Feb 08 '13 at 11:04
  • @kleopatra's [answer](http://stackoverflow.com/a/14771059/230513) is dispositive; don't hesitate to accept that answer, but please update your question to reflect the intent to affect _all_ renderers. – trashgod Feb 08 '13 at 11:11
  • @kleopatra thanks for your reply. I'll accept your answer as the correct answer I was looking for – adrien.pain Feb 08 '13 at 11:17
2

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);   
kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • thanks for the JXTable example. I updated my project, so now I use only JXTables. It got a nice high(er)-level API, and suits perfectly my needs. Thanks again ! – adrien.pain Feb 08 '13 at 11:36