TableCellEditor#getTableCellEditorComponent接收视图坐标的行索引和列索引吗?

问题描述

我正在编写一个TableCellEditor实现,该实现需要从基础TableModel中获取一些数据。为此,我需要TableModel的行和列索引。

我想知道的是getTableCellEditorComponent()接收到的索引是视图坐标还是模型坐标。换句话说,以下代码中的table.convertRowIndexToModel()table.convertColumnIndexToModel()调用是否必要?还是直接将这些标记直接传递到model.getValueAt()可以吗?

class MyTableCellEditor implements TableCellEditor {

    @Override
    public Component getTableCellEditorComponent(JTable table,Object value,boolean isSelected,int row,int column) {
        TableModel model = table.getModel();

        // is this necessary?
        int rowForQueryingModel = table.convertRowIndexToModel(row);
        int colForQueryingModel = table.convertColumnIndexToModel(column);

        Object valueFromModel = model.getValueAt(rowForQueryingModel,colForQueryingModel);
        return createComponent(valueFromModel);
    }
   ...
}

解决方法

单元格渲染器接收视图坐标。这对于执行诸如对偶数行和奇数行或列进行不同着色等操作很有用。由于已经提供了实际值作为参数,因此未将获取数据视为主要目标。

如果由于某种原因需要访问模型数据,则必须转换坐标。

您可以使用一个简单的示例程序轻松地检查它:

public class CellRendererTest {
    public static void main(String... args) {
        if(!EventQueue.isDispatchThread()) {
            EventQueue.invokeLater(CellRendererTest::main);
            return;
        }
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch(ReflectiveOperationException | UnsupportedLookAndFeelException ex) {}

        JFrame frame = new JFrame("Test");
        Object[][] data = new Object[10][10];
        String[] name = new String[10];
        for (int ix = 0; ix < data.length; ix++) {
            data[ix][0] = ix + 1;
            data[ix][1] = new String(Character.toChars('A' + ix % 3));
            name[ix] = new String(Character.toChars('A' + ix));
        }
        JTable table = new JTable(data,name);
        table.setAutoCreateRowSorter(true);
        DefaultTableCellRenderer r = new DefaultTableCellRenderer();
        table.setDefaultRenderer(Object.class,(t,val,s,f,row,column) ->
                r.getTableCellRendererComponent(t,val != null? val: row+","+column,column));
        frame.setContentPane(new JScrollPane(table));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

您可以通过拖动列标题来更改列顺序,或者通过单击A或B的列标题来对数据进行排序以对数据进行排序,但是提供了其他显示rowcolumn参数的单元格呈现器将继续反映其视觉位置。