Swing 自定义JTable 多选框 自动选择的错误
自定义的TableModel:
import javax.swing.table.AbstractTableModel; /** * @Author: liuxianglin * @Date: 2019/1/15 09:55 * @Description: 自定义JTableModel */ public class CheckBoxTableModel extends AbstractTableModel { // 表头数据 private String[] head; // 类型数组 private Class[] typeArray; // 表格数据 private Object[][] data; // 可编辑的列 private int[] checkBoxArray; public CheckBoxTableModel(String[] head, Class[] typeArray, Object[][] data, int... check) { this.head = head; this.typeArray = typeArray; this.data = data; this.checkBoxArray = check; } // 获得表格的列数 public int getColumnCount() { return head.length; } // 获得表格的行数 public int getRowCount() { return data.length; } // 获得表格的列名称 @Override public String getColumnName(int column) { return head[column]; } // 获得表格的单元格的数据 public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } // 获取所有的数据 public Object[][] getAllDate() { return data; } // 使表格具有可编辑性 @Override public boolean isCellEditable(int rowIndex, int columnIndex) { if (checkBoxArray.length > 0) { for (int checkBox : checkBoxArray) { if (checkBox == columnIndex) { return true; } } } return false; } // 替换单元格的值 @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { data[rowIndex][columnIndex] = aValue; fireTableCellUpdated(rowIndex, columnIndex); } // 实现了如果是boolean自动转成JCheckbox 返回每一列的数据类型 public Class getColumnClass(int columnIndex) { return typeArray[columnIndex]; } }
JTable的建立
/**JTable*/ // 头数据 String[] headArray = {"选择", "货号", "品名", "数量", "价格"}; // 类型 Class[] typeArray = {Boolean.class, String.class, String.class, String.class, String.class}; // TODO 测试数据 Object[] data1 = {false, "115", "商品名称", "1.00", "100.00"}; Object[][] data = {data1, data1, data1, data1, data1, data1, data1, data1, data1}; // 复选框 JCheckBox checkbox = new JCheckBox(); // 建立模型 CheckBoxTableModel tableModel = new CheckBoxTableModel(headArray, typeArray, data, 0); // 创建表格 tblList = new JTable(tableModel); // 设置表格的单元格宽度 tblList.getColumnModel().getColumn(0).setPreferredWidth(50); tblList.getColumnModel().getColumn(1).setPreferredWidth(100); tblList.getColumnModel().getColumn(2).setPreferredWidth(300); tblList.getColumnModel().getColumn(3).setPreferredWidth(50); tblList.getColumnModel().getColumn(4).setPreferredWidth(100); // 获取第一个列的数据 TableColumn firstTableColumn = tblList.getColumnModel().getColumn(0); // 设置第一列的表格类型 firstTableColumn.setCellEditor(new DefaultCellEditor(checkbox)); // 设置横向不显示滚动条,纵向当超出时显示滚动条 JScrollPane jsp = new JScrollPane(tblList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // 设置大小 jsp.setPreferredSize(new Dimension(590, 210));
使用的时候发现一个问题,当选择第一个后,再选择其他复选框时,两个之间的也会被选择。
随后发现是地址值的问题,因为前面的二维数组的单个元素的地址是一样的,是同一个对象,所以在添加数组元素的
时候不能直接用同一个元素,而是每次都要new 一个出来。
更改后的代码:
// TODO 测试数据 Object[] data1 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data2 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data3 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data4 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data5 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data6 = {false, "115", "商品名称", "1.00", "100.00"}; Object[] data7 = {false, "115", "商品名称", "1.00", "100.00"}; Object[][] data = {data1, data2, data3, data4, data5, data6, data7};
测试,成功!