簡體   English   中英

Java JTable 禁用單單元格選擇邊框高亮

[英]Java JTable disable single cell selection border highlight

我有一個每行三列的 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());

但仍然得到邊界

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作為基礎渲染器,並將組件的BordernoFocusBorder ,它在DefaultTableCellRenderer定義為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;
        }
    }
}

可以肯定的是,我更改了setBorder(noFocusBorder); 到...

if (hasFocus) {
    setBorder(new LineBorder(Color.RED));
}

在此處輸入圖片說明

從表面上看,訪問者列類類型沒有被TableModel報告為String ......

更新了代理渲染器概念

因為您想從每個單元格中刪除焦點邊框。 你有三個選擇...

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

這意味着我們可以在不知道可能是什么的情況下利用已經可用的默認渲染器,但也可以為其提供我們自己的自定義要求......

如果您絕對不需要該表中任何單元格的邊框,只需將MyRenderer應用於所有單元格,而不管類如何。 你可以這樣做:

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

除了創建自己的 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