5

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

在此处输入图像描述

出于某种原因,取决于我选择的列,我在上图中得到了它周围的小深蓝色边框(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());

但仍然得到边界

4

3 回答 3

15

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基本渲染器并将组件设置BordernoFocusBorderDefaultTableCellRendererEmptyBorder

然后,您需要将此渲染器设置为受影响列的默认渲染器。查看如何使用表格了解更多详情

更新示例

对我来说很好...

在此处输入图像描述

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));
}

在此处输入图像描述

从外观上看,访问者列类类型没有被报告StringTableModel...

更新了代理渲染器概念

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

  1. Class为您的表格可能需要的每种可能的类型编写一个自定义单元格渲染器。这可能会很耗时,并且会重复大量代码以达到很小的效果。
  2. 什么都不做...
  3. 使用“代理”渲染器。这是一个渲染器,它使用另一个渲染器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)));

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

于 2013-09-14T11:17:42.163 回答
1

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

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

于 2014-02-27T13:18:22.850 回答
1

除了创建自己的 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;
}

于 2021-02-10T20:56:43.597 回答