I am trying to make my table select an entire row when you click on a cell (which can be done by turning off column select), but, I don't want the extra thick border around the specific cell you clicked to be highlighted. I was hoping this would be easy but apparently it involves renderers so I did a lot of research and the closest I can get is this:
JTable contactTable = new JTable(tableModel);
contactTable.setCellSelectionEnabled(true);
contactTable.setColumnSelectionAllowed(false);
contactTable.setRowSelectionAllowed(false);
contactTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// This renderer extends a component. It is used each time a
// cell must be displayed.
class MyTableCellRenderer extends JLabel implements TableCellRenderer {
// This method is called each time a cell in a column
// using this renderer needs to be rendered.
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
// 'value' is value contained in the cell located at
// (rowIndex, vColIndex)
if (isSelected) {
// cell (and perhaps other cells) are selected
}
if (hasFocus) {
// this cell is the anchor and the table has the focus
this.setBackground(Color.blue);
this.setForeground(Color.green);
} else {
this.setForeground(Color.black);
}
// Configure the component with the specified value
setText(value.toString());
// Set tool tip if desired
// setToolTipText((String)value);
// Since the renderer is a component, return itself
return this;
}
// The following methods override the defaults for performance reasons
public void validate() {}
public void revalidate() {}
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
}
int vColIndex = 0;
TableColumn col = contactTable.getColumnModel().getColumn(vColIndex);
col.setCellRenderer(new MyTableCellRenderer());
I copied the Renderer from an example and only changed the hasFocus() function to use the colors I wanted. Setting colors in isSelected()
did nothing.
The problem with this code is:
It only works on one column specified by vColIndex at the bottom. Obviously I want this applied to all columns so clicking on a cell in one highlights the entire row. I could make a for loop to change it to every cell but I figure there's a better way of doing this that changes the cellRenderer for ALL columns at once.
setForegroundColor()
works to change text butsetBackgroundColor()
does nothing to the cells background. I would like it to actually change the background color like the property implies.- Solution for #2: Use
this.setOpaque(true);
before assigning backgroundcolor.
- Solution for #2: Use
When the renderer does work, it only works on a single Cell. How can I get it to color all the Cells in the row?
- Solution for #3: I figured it out! Instead of using
hasFocus()
, which only affects the single cell, if you enable row selection (table.setRowSelectionAllowed(true)
) then you put the color changing in theif(isSelected)
statement. Then the whole row is considered selected and it colors all the cells in!
- Solution for #3: I figured it out! Instead of using
3 was the big one but if anyone knows #1 or can explain to me why it was designed such that you can only apply the renderer to one column at a time it would be much appreciated.