源代码如下:package net.test;import java.awt.BorderLayout;
import java.awt.Dimension;import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;import net.util.OwerFrame;
public class TestJTable implements TableModelListener,ListSelectionListener
{
private JPanel contentPane;
private JTable jTable;
private DefaultTableModel defaultModel;
private JScrollPane js;
private JLabel jLabel;

public TestJTable()
{
defaultModel = new DefaultTableModel()
{ @Override
public boolean isCellEditable(int row, int column)
{
if(column == 3)
{
return false;
}

return true;
} };
defaultModel.addColumn("第一列");
defaultModel.addColumn("第二列");
defaultModel.addColumn("第三列");
defaultModel.addColumn("第四列");
defaultModel.addRow(new String[]{"1","2","3"});
defaultModel.addRow(new String[]{null});
defaultModel.addTableModelListener(this);

jTable = new JTable(defaultModel);
jTable.setPreferredScrollableViewportSize(new Dimension(300,50));
jTable.setCellSelectionEnabled(true);

// listSelectionModel = jTable.getSelectionModel();
// listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// listSelectionModel.addListSelectionListener(this);
jTable.getSelectionModel().addListSelectionListener(this);
jTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

js = new JScrollPane(jTable);
jLabel = new JLabel("你选取的数据是:");

contentPane = new JPanel(new BorderLayout());
contentPane.add(js,BorderLayout.CENTER);
contentPane.add(jLabel,BorderLayout.SOUTH);

new OwerFrame(300,300,"测试JTable",contentPane).pack();
}



@Override
public void tableChanged(TableModelEvent e)
{
defaultModel.removeTableModelListener(this);
int row = e.getFirstRow();
int value = 0;
String str0 = (String)defaultModel.getValueAt(row, 0);
String str1 = (String)defaultModel.getValueAt(row, 1);
String str2 = (String)defaultModel.getValueAt(row, 2);

try
{
int column0 = Integer.parseInt(str0);
int column1 = Integer.parseInt(str1);
int column2 = Integer.parseInt(str2);
int column3 = column0 + column1 + column2;
value = column3;
}

catch(Exception exception)
{
jTable.setValueAt(new String("0"), row, e.getColumn());
jTable.setValueAt(new String("0"), row, 3);
JOptionPane.showMessageDialog(null, "请输入一个整数","警告",JOptionPane.ERROR_MESSAGE);
defaultModel.addTableModelListener(this);
return;
}
// jTable.setValueAt(new String(new Integer(value).toString()), row, 3);
defaultModel.addTableModelListener(this);
jTable.repaint();
} @Override
public void valueChanged(ListSelectionEvent e)
{
jTable.getSelectionModel().removeListSelectionListener(this);
int[] rows = jTable.getSelectedRows();
int[] cols = jTable.getSelectedColumns();

System.out.println("------");
jLabel.setText("你选择的数据为:" + jTable.getValueAt(rows[0], cols[0]));
System.out.println("已执行");
jTable.revalidate();
} public static void main(String args[])
{
new TestJTable();
}
}
主要存在两个监听问题:
1.编辑监听。如果不在事件响应方法中先去掉(defaultModel.removeTableModelListener(this);)监听,然后等所有操作结束,在末位再重新加上监听(defaultModel.addTableModelListener(this);),那么就会无限循环下去。会报栈满错误。
2.选择监听问题。程序里用的是单一选择,第一次点击任意一个单元格之后,被监听的方法会被执行两次。就是说第一次点击任意单元格之后(valueChange(ListSelectionEvent e)会被执行两次。而之后,再点击同一行的另外一单元格,监听的方法不执行。比如说原来点击的是(0,1)格,监听方法执行两次,再点击(0,2)格或者其他(0,Y)格,方法都不再执行。必须点击其他行监听方法才能再次执行。请问这两个方法怎么解决?需要重写什么类或接口吗?