Swing 自定義JTable 多選框 自動選擇的錯誤

l48x4264l46發表於2019-01-18
自定義的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};

測試,成功!







相關文章