1

There is a common method when using JTable TableCellRenderers for setting the background and foreground when the cell is selected. Here is an example question that was asked:

Why does my Java custom cell renderer not show highlighting when the row/cell is selected?

This solution is lacking one thing ... the border around the cell. (Note I am not asking about a border around the row, as was asked here.) The border should highlight when the cell is selected. It is not acceptable to just create your own Border, and set it, because the border you create may not fit in with the Look & Feel.

I've successfully got the border by initializing a default renderer, and then scavenging it for its border, as follows:

private final DefaultTableCellRenderer defTblRend = new DefaultTableCellRenderer();
private final JComponent renderer = new ComplexCell(); // Whatever object type extends JComponent
@Override public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus, int row,
    int column)
{
    // ... Set values on "renderer" object here ...
    renderer.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
    renderer.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
    renderer.setOpaque(!renderer.getBackground().equals(table.getBackground()));
    JComponent comp = (JComponent)defTblRend.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    renderer.setBorder(comp.getBorder());
    return renderer;
}

Is there a better way?

Community
  • 1
  • 1
Pixel
  • 374
  • 5
  • 15
  • Note that `getBorder()` may return `null`. – trashgod Jun 02 '11 at 17:03
  • agreed with trashgod and now return back to the camickr example about prepareRenderer, well that basic workAround, more better as take Component(missed) and with JComponent, note: if isn't here AWT Component or Custom Painting, then playing with Opacities dosn't make any sense ..., build prepareRenderer(that's accepted by majorities of Custom L&F) and if is there needed make som changes for some TabelColumn(s) then add TableRenderer, you can combine that together – mKorbel Jun 02 '11 at 18:58

1 Answers1

2

You might be able to use the UIManager. See UIManager Defaults. "Table.focusCellHighlightBorder" would appear to be the property you want.

ADDED BY ORIGINAL POSTER:

Here is the solution I came up with based on camickr's info. Optimizations/cleanup welcome.

  1. Set up static borders so they are available wherever you need them (I put them in a class called "UiUtils"):

    public static final Border focusedCellBorder = UIManager.getBorder("Table.focusCellHighlightBorder");
    public static final Border unfocusedCellBorder = createEmptyBorder();
    private static Border createEmptyBorder()
    {
        Insets i = focusedCellBorder.getBorderInsets(new JLabel());
        return BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);
    }
    
  2. Renderer

    @Override public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column)
    {
        // [... set component values here ...]
        label.setBorder(hasFocus ? UiUtils.focusedCellBorder : UiUtils.unfocusedCellBorder);
        return label;
    }
    
Pixel
  • 374
  • 5
  • 15
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Interesting that there is no Table.cellHighlightBorder (without the focus) to go along with it. – Pixel Jun 02 '11 at 20:26
  • @Pixel, I believe it is just an EmptyBorder with the insets set to be the same size as the highlight border so you don't see the text shift as the border is changed from normal to highlight. – camickr Jun 03 '11 at 00:00