江西广告网

标题: 思维要向上,研究要向底层 [打印本页]

作者: 引章小姐     时间: 2009-2-5 10:37
标题: 思维要向上,研究要向底层
最近产品需要在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类架构的原理,从思维方面解决遇到难题, 提升思维高度,研究底层代码。




欢迎光临 江西广告网 (http://bbs.jxadw.com/) Powered by Discuz! X3.2