I have a Jtable and I want to highlight a row by adding a border to the row. I have extended a DefaultTableCellRenderer
and I figure the work needs to be done i
You have the correct idea in mind, you will need to set the border on the label in the cellrenderer depending on where it is in the table(i.e. edge, center etc).
Take a look at matteborder. You can specify which areas to draw a border along w/ width and color.
I agree with > camickr the best way to go is to override the prepareRendere method. The following code will create a border for a row with a selected cell:
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent)c;
if (isRowSelected(row)){
int top = (row > 0 && isRowSelected(row-1))?1:2;
int left = column == 0?2:0;
int bottom = (row < getRowCount()-1 && isRowSelected(row + 1))?1:2;
int right = column == getColumnCount()-1?2:0;
jc.setBorder(BorderFactory.createMatteBorder(top, left, bottom, right, this.getSelectionBackground()));
}
else
jc.setBorder(null);
return c;
}
I would not create a custom renderer for this. Yes it will work if all your data is of the same type. But what happens when you start to mix Strings, with Dates and Integers and Booleans which all use different renderers? Then you would need to create 4 custom renderers.
The better approach is to override the prepareRenderer(...) method JTable so you can add the code in one place. Here is an example to get you started. In reality you would want to use a CompoundBorder that contains a MatteBorder for the top/bottom and and EmptyBorder for the left/right and you would create a single instance of the Border.
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.border.*;
public class TablePrepareRenderer extends JFrame
{
JTable table;
public TablePrepareRenderer()
{
Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
Object[][] data =
{
{"Buy", "IBM", new Double(1000), new Double(80.5), Boolean.TRUE},
{"Sell", "MicroSoft", new Double(2000), new Double(6.25), Boolean.TRUE},
{"RSell", "Apple", new Double(3000), new Double(7.35), Boolean.TRUE},
{"Buy", "Nortel", new Double(4000), new Double(20), Boolean.TRUE}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable( model )
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
public Component prepareRenderer(
TableCellRenderer renderer, int row, int column)
{
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent)c;
// Color row based on a cell value
// Alternate row color
if (!isRowSelected(row))
c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY);
else
jc.setBorder(new MatteBorder(1, 0, 1, 0, Color.RED) );
// Use bold font on selected row
return c;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.changeSelection(0, 0, false, false);
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
}
public static void main(String[] args)
{
TablePrepareRenderer frame = new TablePrepareRenderer();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}