The TableCellRenderer
is responsible for drawing the focus rectangle around the currently focused cell. You need to supply your own renderer that is capable of either overriding this feature or providing its own...
For example;
public class MyRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setBorder(noFocusBorder);
return this;
}
}
This uses the DefaultTableCellRenderer
as the base renderer and sets the component's Border
to noFocusBorder
which is defined in DefaultTableCellRenderer
as a EmptyBorder
You will then need to set this renderer as the default renderer for the effected columns. Check out How to use tables for more details
Update with example
Works fine for me...
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TableRenderer {
public static void main(String[] args) {
new TableRenderer();
}
public TableRenderer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultTableModel model = new DefaultTableModel(new Object[][]{{"", "One"}, {"", "Two"}}, new Object[]{"Check", "Vistor"}) {
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
};
JTable table = new JTable(model);
table.setRowSelectionAllowed(true);
table.setShowGrid(false);
table.setDefaultRenderer(String.class, new VisitorRenderer());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class VisitorRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setBorder(noFocusBorder);
return this;
}
}
}
And just to be sure, I changed setBorder(noFocusBorder);
to...
if (hasFocus) {
setBorder(new LineBorder(Color.RED));
}
From the looks of things, the visitor column class type isn't being reported as String
by the TableModel
...
Updated with proxy renderer concept
Because you want to remove the focus border from every cell. You have three choices...
- Write a custom cell renderer for every possibility of
Class
type you might need for your table. This can time consuming and repeats a lot of code to achieve only a small effect.
- Do nothing a live with it...
- Use a "proxy" renderer. This is a renderer that uses another
TableCellRenderer
to perform the actual rendering process, but applies some minor changes to the result, for example, remove the border...
...
public static class ProxyCellRenderer implements TableCellRenderer {
protected static final Border DEFAULT_BORDER = new EmptyBorder(1, 1, 1, 1);
private TableCellRenderer renderer;
public ProxyCellRenderer(TableCellRenderer renderer) {
this.renderer = renderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (comp instanceof JComponent) {
((JComponent)comp).setBorder(DEFAULT_BORDER);
}
return comp;
}
}
Instead of doing something like...
table.setDefaultRenderer(String.class, new VisitorRenderer());
Which we did before, we would do this instead...
table.setDefaultRenderer(String.class,
new ProxyCellRenderer(table.getDefaultRenderer(String.class)));
This means we can take advantage of the what ever default renderer is already available without knowing what that might be, but also supply our own custom requirements to it...
String.class
by yourTableModel
... – Heribertoheringer