分类:
2008-10-28 17:46:45
最近产品需要在JTable中显示JComboBox,It‘s easy,
在java application中,如果swing界面需要在表格中显示JComboBox,通常会使用JTable 的Editor方法,
但是表格中有几列的值需要根据JComboBox的选择而改变,这几列是否可以编辑也要根据JComboBox的选择而改变,
首先的思路是表格加入Jcombobox之后,给JComboBox加监听,addActionListener,或者addItemListener,都可以,
为了专业一点,还是添加ItemListener比较好,因为这个是JComboBox常用的。
思路就是这样,鼠标点击表格的一行,得到表格的选中行,从JComboBox的监听中得到选中的Item,
根据选择判断是否向固定列赋值,
编码:
为了灵活首先要继承一个DefaultCellEditor
public class ComboEditor extends DefaultCellEditor
{
public ComboEditor() {
super(new JComboBox());
}
public boolean isCellEditable(EventObject eventObject) {
return true;
}
}
JTable m_table = new JTable()
ComboEditor editorSignalType = null;
JComboBox boxSignalType = null;
editorSignalType = getComboEditor();
m_table.getColumnModel().getColumn(0).setCellEditor(editorSignalType);
boxSignalType.addItemListener(this);
private ComboEditor getComboEditor() {
ComboEditor editor = new ComboEditor();
boxSignalType = (JComboBox) ((ComboEditor) editor).getComponent();
boxSignalType.removeAllItems();
//给JComboBox赋值 ........ //
return editor;
}
JComboBox事件处理:
public void itemStateChanged(ItemEvent e) {
Object[] obj = item.getItemSelectable().getSelectedObjects();
int selectRow = m_table.getSelectedRow();
//向表格赋值
setTableRowData(obj[0].toString(),selectRow);
}
……编译ing
调试ing
问题出现了,selectRow不是当前选中的行,是前一个选中的行号,为什么会出现这种状况? 原因是点击表格中的JComboBox时,ItemListener先捕捉到事件,执行itemStateChanged时候JTable还没有选中, selectRow是-1或者前次选中的行数,怎么办? 修改思路,让程序先得到选中的表格行号,在去执行JComboBox的监听事件:具体的实现方法呢? 众所周知,软件的实现有很多种方法,如果是一个沉迷界面乐趣的人方法大概会这样:
A 给表格添加mouseListener,
B 点击表格时先得到选中行,
C 给JComboBox添加监听器,
D 触发JComboBox事件执行事件处理方法,
E 移除JComboBox添加监听器
这是一个使用java GUI 熟练的人的思路,很酷很复杂,多个监听混在一起复杂度大大增加,实际也是这样, 调试相当的麻烦,并不能很好的达到目的,这个方法还有一个缺点,用很表层的方法来处理问题,没有认识到javaGUI的设计本质。 该可以想到的,软件的设计不会让使用者用一个很复杂的方法来实现一个功能,应该有更好的方法,那么该如何实现? 这时需要安静下来想一下:JTable Editer ,它的功能是把JComboBox放到JTable的一个格内,既然已经放进去了,那么CellEditor 一定已经得到这个表格单元格的行和列了,显然用m_table.getSelectedRow();是错误的,应该向swing的底层实现思考, 看看DefaultCellEditor的源码,不难找到 int column ,int row的字样,把他们得到取出来如何?
修改之前的实现:
修改 ComboEditor:
public class ComboEditor extends DefaultCellEditor
{
public ComboEditor() {
super(new JComboBox());
}
public boolean isCellEditable(EventObject eventObject) { return true; }
//**第二次修改添加*********************************************
private int row;
private int column;
public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column)
{
this.row = row;
this.column = column;
return super.getTableCellEditorComponent(table,value,isSelected,row,column);
}
public int getRow(){
return row;
}
public int getColumn(){
return column;
}
//**************************************************
}
修改 JComboBox事件处理:
public void itemStateChanged(ItemEvent e) {
Object[] obj = item.getItemSelectable().getSelectedObjects();
int selectRow = editorSignalType.getRow();
//向表格赋值
setTableRowData(obj[0].toString(),selectRow);
}
……编译ing
调试ing
OK 所得到的行号就是点击JComboBox的那行,这个思路是对的,而且简单的多,问题解决了。
总结:
解决复杂的难题需要提升思考的高度,分析java的源码,根据需要写出自己需要的东西,
最好理解java类架构的原理,从思维方面解决遇到难题,
提升思维高度,研究底层代码。