为JTable每行按钮单独设定点击状态
最近工作忙到头大,看到eclipse要吐……遇到的问题也很多,有个比较奇怪的问题描述是这样的:JTable有MxN个cell,其中第5列为按钮,按钮可点击一次,之后变为disable状态;其他列为不可编辑的文本内容。
分析
拿到这个问题首先是创建abstractTableModel
,然后创建以此Model为内容的JTable,接着创建按钮显示,用TableCellRenderer
和TableCellEditor
,创建样式和响应事件。
一般到这里,创建的table就可以正常显示并且内容按钮也能响应了。但是作为主要功能,每行按钮只能点击一次,并且不影响其他按钮的效果才是关键。
直接在render和editor里设置返回button的状态肯定不行,因为是按照table.getColumnModel().getColumn(5).setCellRenderer(render);
来指定,即按列改变状态。点击一次全部取消掉,那其他行的按钮就没办法用了。
挠头挠了半天,终于想到&找到解决办法了。
关键点在AbstractTableModel
这里。isCellEditable
这个函数是用于cell是否可编辑的,通常如果包含按钮的话,就用getColumnClass(col).equals(JButton.class)
来判断,并返回true,其他返回false,即不可编辑。
以此为突破口,只要在TableModel里加入行列和可否编辑的信息并存储就行了。那就是……双key单value?这肯定不行。
解决办法 Map:cell row & column, key
最后想到在AbstractTableModel
里加上了一个Map
,其中CellEditableKey
包含row和column元素,即该tableModel
的行和列信息,然后以Map来存放行列对应的Boolean信息。
public class CellEditableKey{
private int row;
private int column;
public CellEditableKey(int row, int column){
this.setRow(row);
this.setColumn(column);
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
}
另外加入两个函数addCellEditable
和setCellEditable
,分别在插入数据的时候和更改cell的可编辑状态时用。该部分代码如下
public void addCellEditable(CellEditableKey mKey, boolean value) {
for (CellEditableKey key : map.keySet()) {
if (key.getRow() == mKey.getRow()
&& key.getColumn() == mKey.getColumn()) {
return;
}
}
map.put(mKey, value);
}
public void setCellEditable(int row, int col, boolean value) {
for(CellEditableKey key : map.keySet()){
if(key.getRow() == row && key.getColumn() == col){
map.put(key, value);
}
}
if(getColumnClass(col).equals(JButton.class)){
JButton btn = (JButton)getValueAt(row, col);
btn.setEnabled(value);
}
this.fireTableCellUpdated(row, col);
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
for(CellEditableKey key : map.keySet()){
if(key.getRow() == rowIndex && key.getColumn() == columnIndex){
return map.get(key);
}
}
return false;
}
这样,为TableCellEditor
绑定ActionListener
之后,在actionPerformed
里触发一个
getControlModel().setCellEditable(row, 5, false);
即可单独改变单个按钮状态,在这里再用一个clicked来记录是否点击,以避免重复触发,即可实现需要的功能了。
结论
Java的UI变数好大,很多问题怎么绕弯,最后都可以解决。关键就是动脑筋&办法效率了。作为一个新手,能解决问题是好的,慢慢就要想更精简&有效率的方法了。程序员果然是为“懒”而生的。
欢迎有类似问题经验的同学赐教。
这个对我来说有点难
这个对我来说是天文~其实早就进来过,看不懂没吭声,再来不吭声就不是大叔了
@zwwooooo 谢谢大叔,55555
这是java吧,所有编程都差不多,就是要去死记硬背多敲代码才会熟悉一些控件语法等。 写代码虽然很累,但是实现了还是很有成就感的,呵呵。
你知道的,我是在看天书···
思路很清晰。