TableCellRenderer
负责在当前聚焦的单元格周围绘制聚焦矩形。您需要提供自己的渲染器,以便覆盖此功能或提供自定义实现...。
例如:
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;
}
}
这里使用了DefaultTableCellRenderer
作为基本渲染器,并将组件的Border
设置为noFocusBorder
,该值在DefaultTableCellRenderer
中定义为EmptyBorder
然后需要将此渲染器设置为所需列的默认渲染器。详见如何使用表格
示例更新
对我来说工作得很好...
![enter image description here](https://istack.dev59.com/L94w3.webp)
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;
}
}
}
为了确保,我将setBorder(noFocusBorder);
更改为...
if (hasFocus) {
setBorder(new LineBorder(Color.RED));
}
![在此输入图片描述](https://istack.dev59.com/Kjb9z.webp)
从现有的情况来看,访客列的类类型在TableModel
中没有被报告为String
...
使用代理渲染器概念进行更新
因为您希望从每个单元格中移除焦点边框。您有三种选择...
- 为可能用于表格的每种
Class
类型编写自定义单元格渲染器。这可能很耗时,并且重复了大量代码以实现仅获得小的效果。
- 不做任何处理,并接受它的存在...
- 使用“代理”渲染器。这是一种渲染器,它使用另一个
TableCellRenderer
执行实际的渲染过程,但对结果应用一些微小的更改,例如删除边框...
...
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;
}
}
不要像这样做...
table.setDefaultRenderer(String.class, new VisitorRenderer());
我们以前做过的,现在将会改为这样做...
table.setDefaultRenderer(String.class,
new ProxyCellRenderer(table.getDefaultRenderer(String.class)));
这意味着我们可以利用已经可用的任何默认渲染器,而无需知道它是什么,但也可以向其提供自己的自定义要求...
String.class
... - MadProgrammerProxyCellRenderer
,它接受另一个TableCellRenderer
,用它作为呈现给定单元格内容的机制,但将边框设置为EmptyBorder
,这样你就可以获取正在使用的默认渲染器,并将它们通过这个代理渲染器传递。 - MadProgrammer