关于javaSwing的JTable插入复选框,并且复选框可以居中,可以设置数量限制和点击限制。
搜了很多文章,但发现并不合我意,没有我想要的需求,本篇文章的重点就是,让JTable中的复选框可以有数量限制,首先说一下效果,假如有五个复选框,你想让用户只能点击两个,当点击第三个的时候就会留下后两次选择的,看不懂没关系,后边我会有演示,闲话不说上代码。
/**
* 此类不用单独创建,可以当一个内部类使用,写到你生成JTable的那个类里,
* 然后用你创建的JTable.setModel(new MyTableMode)来实现JTable插入复选框
*/
class MyTableModel extends AbstractTableModel {
//这是每列名字,有几个写几个
private Object[] columnNames = {"name", "choose"};
/*这是插入的数据就按着我写的说了,第一列不用照着我的,可以用中英文,第二列就得用到boolean值,
这里要设置成一个变量的boolean值,后边要更新它达到限制效果,而且这个要设置成全局变量放到这个类的外边,
再次声明,我用的内部类写法*/
private Object[][] rowData = {{"\u8bfe\u7a0b\u4e00", cou0},
{"\u8bfe\u7a0b\u4e8c", cou1},
{"\u8bfe\u7a0b\u4e09", cou2},
{"\u8bfe\u7a0b\u56db", cou3},
{"\u8bfe\u7a0b\u4e94", cou4}};
@Override
public int getRowCount() {
return rowData.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column].toString();
}
/**
* 这里以及紧接着的下边的那个函数必须要有,这里就让这个复选框居中和展现出来,
* 就不用去写渲染器了,也不用别的方法
*/
Class<?>[] columnTypes = new Class<?>[]{
Object.class, Boolean.class
};
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnTypes[columnIndex];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return rowData[rowIndex][columnIndex];
}
//因为我是第二列需要编辑就设置了column=1,column是列的索引,这里也是必须要设置的
@Override
public boolean isCellEditable(int row, int column) {
if (column == 1) {
return true;
} else {
return false;
}
}
//不必在意,可有可无这个
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
rowData[rowIndex][columnIndex] = aValue;
//只需要更新对应的位置
this.fireTableCellUpdated(rowIndex, columnIndex);
}
}
/**
* 这是我给JTable加入Model和此功能的核心处,当然有更好的方法,可惜我不想再去想了,累
*/
public void table_init() {
/*这里首先来一个集合,用来存储选中的复选框,这里有人可能好奇你也没定义复选框啊,实际我这里
存的是选中复选框的行,复选框在上边那个类里就会通过设置的布尔值和重写的方法实现
*/
List<Integer> list = new ArrayList<>();
//集合首先添加一个100是因为我用不到100行,而且我不让集合初始有数据我下边就没法通过for给集合添加数据,
//这里应该有更好的解决思路
list.add(100);
table1.setModel(new MyTableModel());
//给表格加入点击监听,因为我在表格的单元格改变那个监听遇到了bug,没有解决掉就改成了鼠标监听
table1.addMouseListener(new MouseAdapter() {
//不要用click点击监听,如果速度过快就会识别为双击,有bug
@Override
public void mousePressed(MouseEvent e) {
//用到后边判断我到后便会说道为啥要放到重写的函数里定义
int flag=0;
if (e.getClickCount() == 1) {
int row = table1.getSelectedRow();
int column = table1.getSelectedColumn();
//复选框在哪列填多少,限制鼠标点击的位置
if (column == 1) {
//这里一定要先判断而且要用这种方法 不能用for each 不然会有bug在remove产生
//具体可以在这篇文章研究
//https://blog.csdn.net/kingzone_2008/article/details/41368989?ops_request_misc=&request_id=&biz_id=102&utm_term=java.util.ConcurrentModificati&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-5-41368989.pc_search_result_before_js
for (int i = 0; i < list.size(); i++) {
int temp = list.get(i);
if (temp==row)
{
//如果新点击的和之前行一样说明是取消了选中就要移除这个行,并且这一行不能加入到集合中
flag++;
list.remove((Integer)row);
}
}
if (flag==0)
list.add(row);
/* for (Integer sssss : list) {
System.out.print(sssss+" ");
}
System.out.println();*/
//如果集合有了四个,就说明什么,说明有第三个复选框被选中,这时候就要让先选的一个从集合删除
//然后让之前的变量通过判断让还在集合里的变成true
if (list.size()==4) {
list.remove(1);
for (Integer integer1 : list) {
if (integer1 == 0)
cou0 = true;
else if (integer1 == 1)
cou1 = true;
else if (integer1 == 2)
cou2 = true;
else if (integer1 == 3)
cou3 = true;
else if (integer1 == 4)
cou4 = true;
}
//这一步,更新就会让你之前变量变成true的变成选中的
table1.setModel(new MyTableModel());
//然后要让变量又恢复到false,不会影响表格,因为没传进去,方便下一次的更新
cou0=false;
cou1=false;
cou2=false;
cou3=false;
cou4=false;
}
}
}
}
});
}
关键的两处就为上两处
分别是运行,点击第一行,点击第二行,点击第三行,最后那个我按错了,有个全部高亮效果不用在意。
到此结束了,肯定有更好的方法,希望交流!!!