简体   繁体   English

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

[英]Java JTable disable single cell selection border highlight

I have a JTable with three columns in each row, see the image:我有一个每行三列的 JTable,请参见图像:

在此处输入图片说明

For some reason depending on the column i select i get the little dark blue border around it (V140116554) in the image above.出于某种原因,根据我选择的列,我在上图中得到了它周围的深蓝色小边框 (V140116554)。

I currently use this to select the entire row:我目前使用它来选择整行:

vTable.setRowSelectionAllowed(true);

How can i disable this?我怎样才能禁用它?

EDIT:编辑:

Added a class:添加了一个类:

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 added it:并添加了它:

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

But still get the border但仍然得到边界

The TableCellRenderer is responsible for drawing the focus rectangle around the currently focused cell. TableCellRenderer负责在当前聚焦的单元格周围绘制聚焦矩形。 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这使用DefaultTableCellRenderer作为基础渲染器,并将组件的BordernoFocusBorder ,它在DefaultTableCellRenderer定义为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);可以肯定的是,我更改了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 ...从表面上看,访问者列类类型没有被TableModel报告为String ......

Updated with proxy renderer concept更新了代理渲染器概念

Because you want to remove the focus border from every cell.因为您想从每个单元格中删除焦点边框。 You have three choices...你有三个选择...

  1. Write a custom cell renderer for every possibility of Class type you might need for your table.写出的每一个可能的自定义单元格渲染器Class类型,您可能需要为你的表。 This can time consuming and repeats a lot of code to achieve only a small effect.这可能会很耗时,并且会重复很多代码来实现很小的效果。
  2. Do nothing a live with it...什么都不做...
  3. 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...这是一个渲染器,它使用另一个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;
    }        
}

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...这意味着我们可以在不知道可能是什么的情况下利用已经可用的默认渲染器,但也可以为其提供我们自己的自定义要求......

If you have absolutely no need for the border on any cell in that table, just apply MyRenderer to all cells, regardless of class.如果您绝对不需要该表中任何单元格的边框,只需将MyRenderer应用于所有单元格,而不管类如何。 You can do it like this:你可以这样做:

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

Instead of creating your own TableCellRenderer you could also do:除了创建自己的 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM