为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信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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的可编辑状态时用。该部分代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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吧,所有编程都差不多,就是要去死记硬背多敲代码才会熟悉一些控件语法等。 写代码虽然很累,但是实现了还是很有成就感的,呵呵。
你知道的,我是在看天书···
思路很清晰。