Java 行、模型行和视图行的有趣行为-何时使用哪一个?

Java 行、模型行和视图行的有趣行为-何时使用哪一个?,java,swing,jtable,awt,Java,Swing,Jtable,Awt,这是一个很难解释的问题,我将尝试分步骤进行解释,并排运行代码会有所帮助,但查看图像应该足以理解我的问题 row和rowModel分别与数据显示和数据模型一致,但我完全无法理解rowView。rowView什么时候有用 1) 默认视图:B列(1,2,3,4) 2) 单击以对列B标题进行排序:升序排序(1,2,3,4)。始终是dataRow=modelRow=viewRow 3) 单击以对列B标题进行排序:按降序排序(4,3,2,1) 行0=行模型3=行视图3 行1=行模型2=行视图2 行2=行模

这是一个很难解释的问题,我将尝试分步骤进行解释,并排运行代码会有所帮助,但查看图像应该足以理解我的问题

row和rowModel分别与数据显示和数据模型一致,但我完全无法理解rowView。rowView什么时候有用

1) 默认视图:B列(1,2,3,4)

2) 单击以对列B标题进行排序:升序排序(1,2,3,4)。始终是dataRow=modelRow=viewRow

3) 单击以对列B标题进行排序:按降序排序(4,3,2,1)

行0=行模型3=行视图3

行1=行模型2=行视图2

行2=行模型1=行视图1

第3行=行模型0=行视图0

一切如期而至

4) 现在单击排序列C:升序排序(下图)

列0:值“4”--行0=rowModel 3=rowView 2--为什么rowView是2

第1列:值“1”--行0=rowModel 3=rowView 2-- 为什么rowView为2且在剩余单元格中的行为一致,如下所示

列0:值“3”--行1=rowModel 2=rowView 3--为什么rowView是3

列1:值“3”--行1=rowModel 2=rowView 3--为什么rowView是3

列0:值“1”--行2=rowModel 0=rowView 1--为什么rowView是1

列1:值“4”--行2=rowModel 0=rowView 1--为什么rowView是1

列0:值“2”--行3=rowModel 1=rowView 0--为什么rowView为0

第1列:值“5”--第3行=行模型1=行视图0--为什么行视图为0

代码:

import javax.swing.*;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableCellRenderer;
导入javax.swing.table.TableModel;
导入java.awt.*;
公共类SortTableWithColor\uFrame{
公共静态void main(字符串[]args){
SortTableWithColors_uFrame=新的SortTableWithColors_uFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
带有颜色的公共排序表{
对象[]columnNames={“B”,“C”};
对象[][]数据={{新整数(1),新整数(4)},
{新整数(2),新整数(5)},
{新整数(3),新整数(3)},
{新整数(4),新整数(1)};
//表格模型
DefaultTableModel=新的DefaultTableModel(数据、列名称);
//Jtable中的set表模型
JTable table=新的JTable(模型);
表.setAutoCreateRowSorter(真);
getContentPane().add(新的JScrollPane(表));
//告诉表要使用什么来呈现列
对于(int i=0;i<2;i++){
table.getColumnModel().getColumn(i).setCellRenderer(新的NewRenderer());
}
}
//自定义渲染器
公共类NewRenderer扩展了DefaultTableCellRenderer{
@凌驾
公共组件GetTableCellRenderComponent
(JTable表,对象值,布尔值,
布尔值(焦点、整数行、整数列){
JLabel单元格=(JLabel)super.GetTableCellRenderComponent
(表、值、isSelected、hasFocus、行、列);
int rowModel=(int)table.convertRowIndexToModel(行);
int colModel=(int)table.convertColumnIndexToModel(column);
int rowView=(int)table.convertRowIndexToView(行);
int colView=(int)table.convertColumnIndexToView(column);
//定色
单元格背景(新颜色(0xFFFFFF));
cell.setForeground(新颜色(0x000000));
//设置选择颜色
如果(当选){
单元格背景(新颜色(0x4AC3FF));
cell.setForeground(新颜色(0x000000));//AM
}
//基于值的选择性细胞染色
int val=(int)值;
如果(val==1){
单元格.背景(颜色.绿色);
}
返回单元;
}
}
}

请注意,渲染器的
值是视图坐标,因此只有两个转换是有意义的:

int rowModel = (int) table.convertRowIndexToModel(row);
int colModel = (int) table.convertColumnIndexToModel(column);
//int rowView = (int) table.convertRowIndexToView(row);
//int colView = (int) table.convertColumnIndexToView(column);
添加一条线以在括号中显示选定行的模型坐标,以查看效果。未排序时,模型索引和视图索引相同:

if (isSelected) {
    …
    System.out.println(row + " (" + rowModel + ") " + column + " (" + colModel +")");
}
当需要特别警惕时:

  • 因为用户可以通过拖动更改列顺序,所以在访问模型时进行转换,如所示

  • 由于用户可以通过排序更改行顺序,因此在访问
    TableCellRenderer
    TableCellEditor
    ListSelectionListener
    中的模型时进行转换,如图所示


请注意,渲染器的
值是视图坐标,因此只有两个转换是有意义的:

int rowModel = (int) table.convertRowIndexToModel(row);
int colModel = (int) table.convertColumnIndexToModel(column);
//int rowView = (int) table.convertRowIndexToView(row);
//int colView = (int) table.convertColumnIndexToView(column);
添加一条线以在括号中显示选定行的模型坐标,以查看效果。未排序时,模型索引和视图索引相同:

if (isSelected) {
    …
    System.out.println(row + " (" + rowModel + ") " + column + " (" + colModel +")");
}
当需要特别警惕时:

  • 因为用户可以通过拖动更改列顺序,所以在访问模型时进行转换,如所示

  • 由于用户可以通过排序更改行顺序,因此在访问
    TableCellRenderer
    TableCellEditor
    ListSelectionListener
    中的模型时进行转换,如图所示


表格模型中数据的顺序是固定的


JTable
中的数据顺序可能会更改,因为:

  • JTable
    可以被过滤或排序,这意味着
    JTable
    的行号可以不同于
    表格模型中的行号
  • 用户可以对列进行重新排序,这意味着
    JTable
    的列号可以与列号不同
    String firstName = table.getValueAt(selectedRow, table.convertColumnIndexToView(0));
    String lastName = table.getValueAt(selectedRow, table.convertColumnIndexToView(1));
    
    TableModel model = table.getModel();
    int modelRow = table.convertRowIndexToModel( selectedRow );
    String firstName = model.getValueAt(modelRow, 0);
    String lastName = model.getValueAt(modelRow, 1);