Java JTable禁用单个单元格选择边框高亮显示

时间:2013-09-14 11:12:03

标签: java swing jtable border tablecellrenderer

我有一个JTable,每行有三列,见图:

enter image description here

出于某种原因,根据我选择的列,我会在上面的图像中得到它周围的小深蓝色边框(V140116554)。

我目前使用它来选择整行:

vTable.setRowSelectionAllowed(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;
    }
} 

并补充说:

vTable.setDefaultRenderer(String.class, new VisitorRenderer());

但仍然可以获得边框

3 个答案:

答案 0 :(得分:13)

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设置为noFocusBorderDefaultTableCellRenderer中将EmptyBorder定义为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; } } }

然后,您需要将此渲染器设置为受影响列的默认渲染器。查看How to use tables了解更多详情

使用示例更新

对我来说很好......

enter image description here

setBorder(noFocusBorder);

为了确保,我将if (hasFocus) { setBorder(new LineBorder(Color.RED)); } 更改为...

String

enter image description here

从事物的外观来看,TableModel没有将访问者列类类型报告为Class ...

已更新代理渲染​​器概念

因为您想从每个单元格中删除焦点边框。你有三个选择......

  1. 为表格可能需要的TableCellRenderer类型的每种可能性编写自定义单元格渲染器。这可能会耗费大量时间并重复使用很多代码来实现很小的效果。
  2. 无所事事......
  3. 使用“代理”渲染器。这是一个使用另一个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; } } 执行实际渲染过程的渲染器,但对结果应用了一些小的更改,例如,删除边框...
  4. ...

    table.setDefaultRenderer(String.class, new VisitorRenderer());
    

    而不是像...那样做。

    table.setDefaultRenderer(String.class, 
        new ProxyCellRenderer(table.getDefaultRenderer(String.class)));
    

    我们之前做过的,我们会这样做......

    {{1}}

    这意味着我们可以利用默认渲染器已经可用但不知道它可能是什么,但也提供我们自己的自定义要求...

答案 1 :(得分:1)

如果您完全不需要该表中任何单元格的边框,只需将MyRenderer应用于所有单元格,无论是哪个类。你可以这样做:

table.setDefaultRenderer(Object.class, new MyRenderer());

答案 2 :(得分:0)

除了创建自己的 TableCellRenderer,您还可以这样做:

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
    Component c = super.prepareRenderer(renderer, row, col);
        
    if (c instanceof JComponent)
          ((JComponent)c).setBorder(new EmptyBorder(1, 1, 1, 1));
    return c;
}