Question

I have a JTable looking like this:

enter image description here

Is it possible to add a margin for the column text?

I have tried to add a TableCellRenderer and add an EmptyBorder. Problem: the background color gets white like this:

enter image description here

Any idea how to add margin and keep the default background color?

public class JTableColumnMargin extends JFrame {

    public JTableColumnMargin() {
        Object rowData[][] = { { "Row1-Column1", "Row1-Column2", "Row1-Column3" }, { "Row2-Column1", "Row2-Column2", "Row2-Column3" } };
        Object columnNames[] = { "Column One", "Column Two", "Column Three" };
        JTable table = new JTable(rowData, columnNames);

        for (int i = 0; i < table.getColumnCount(); i++) {
            table.getTableHeader().getColumnModel().getColumn(i).setHeaderRenderer(new HeaderRenderer(table));
        }

        JScrollPane scrollPane = new JScrollPane(table);
        this.add(scrollPane, BorderLayout.CENTER);
        this.setSize(500, 150);
        this.setVisible(true);
    }

    private static class HeaderRenderer implements TableCellRenderer {
        private DefaultTableCellRenderer renderer;

        private HeaderRenderer(JTable table) {
            renderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
        }

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
            Component c = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
            JLabel label = (JLabel) c;
            label.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
            return label;
        }
    }

    public static void main(String[] args) {
        new JTableColumnMargin();
    }
}
Was it helpful?

Solution

Delegating to the original renderer basically is the right direction to go, just slightly differently:

  • use a compoundBorder of the original and the emptyBorder
  • nudge the original renderer to re-set the border to its original by making the padded border a UIResource

Something like:

@Override
public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus,
        int row, int column) {
    JComponent comp = (JComponent) originalRenderer.getTableCellRendererComponent(table, value, 
            isSelected, hasFocus, row, column);
    Border originalBorder = comp.getBorder();
    comp.setBorder(new CompoundBorderUIResource(originalBorder, 
            BorderFactory.createEmptyBorder(0, 20, 0, 0)));
    return comp;
}

It's brittle, though, as LAFs might ignore your setting: the trick works fine for WinLAF, but not at all for Nimbus - so don't know the outcome on Mac.

OTHER TIPS

Try to use next header Renderer:

private static class HeaderRenderer extends JLabel implements TableCellRenderer {

    private HeaderRenderer() {
        setBorder(BorderFactory.createCompoundBorder(UIManager.getBorder("TableHeader.cellBorder"),BorderFactory.createEmptyBorder(0, 10, 0, 10)));
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        setText(value.toString());
        return this;
    }
}

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top