老师报置一个用JTable生成学生成绩表的作业,上网找了一些JTable实例并学习了一下.最后自己写了以下代码.
可是当我修改单元格数据时,fireTableCellUpdated()处总是出异常:
         at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(Unknown Source)
我就纳闷!!请教各位高手,不胜感激,谢谢!!!!!!!!
import java.awt.*;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;public class StudentGradeTable implements TableModelListener {
JTable table;
MyTable mytable;

public StudentGradeTable() {
JFrame f = new JFrame();

mytable = new MyTable();
table = new JTable( mytable );
mytable.addTableModelListener( this );

table.setPreferredScrollableViewportSize(new Dimension(600, 80));
JScrollPane s = new JScrollPane(table);
Container contentPane = f.getContentPane();
contentPane.add(s, BorderLayout.CENTER); f.setTitle("学生成绩表");
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
} public void tableChanged(TableModelEvent e) {
for (int i = 0; i < table.getRowCount(); i++) {
double sum = 0;
for (int j = 1; j < table.getColumnCount() - 1; j++) {
if (j == 1 || j == 2) {
sum += 0.2 * ( (( Double )( mytable.getValueAt(i, j))).doubleValue());
} else if (j == 3) {
sum += 0.4 * ((( Double )( mytable.getValueAt(i, j))).doubleValue());
}
// System.out.println( sum );
}
mytable.setValueAt( new Double( sum ), i, table.getColumnCount() - 1 ); //貌似这里错误,不解?
}
}

public static void main(String args[]) {
new StudentGradeTable();
}
}
import javax.swing.table.AbstractTableModel;public class MyTable extends AbstractTableModel {
String[] columnName = { "姓名", "平时成绩(20%)", "期中成绩(20%)", "期未成绩(40%)", "总分" };
Object[][] data = {
{ "张三", new Double(80), new Double(90), new Double(90),
new Double(0) },
{ "李四", new Double(70), new Double(50), new Double(100),
new Double(0) },
{ "王五", new Double(60), new Double(80), new Double(90),
new Double(0) } }; public int getColumnCount() {
return columnName.length;
} public int getRowCount() {
return data.length;
} public String getColumnName(int col) { return columnName[col];
} public Object getValueAt(int row, int col) {
return data[row][col];
} public boolean isCellEditable(int rowIndex, int columnIndex) {
if (columnIndex == 4) {
return false;
} else {
return true;
}
} public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col); //貌似这里有错误,不解?
} public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}

解决方案 »

  1.   

    这是你没有理解事件的机制以及事件之间的传递造成的死循环,最终导致java.lang.StackOverflowError
    栈溢出。你增加了tablemodellistener,监听改变事件。起始点可以看作你修改表格数据,修改之后,fireTableCellUpdated这没有问题,也是应该这样做的。但是这之后,你加的监听会捕获这个事件,看看你做了什么?你又调用了setValueAt方法,也就是说再次给单元格赋值第一次没有问题,你要更改合计数据,但是之后呢?给合计数据设置了value之后,仍然会触发事件,仍然会在setValueAt方法中再次触发fireTableCellUpdated,就这样,无休无止。怎能不挂?换言之,你的事件触发的有问题,或者你可以使用一些判别条件。
      

  2.   

    mytable.setValueAt...这个放在tableChanged事件里,必然出问题,2楼说的没错
      

  3.   


    有道理!!!后来我查看了一下fireTableCellUpdated()的源代码发现 ,方法里面居然又new了一个TableModelEvent().怪不得会栈溢出,晕!!!!-_-!!!!这样我把fireTableCellUpdated()方法删除后,发现tableChanged()不能触发,为什么呢?上网又看了一些做法,另外声明一个方法mySetValueAt(),即把上面setValueAt()方法里的fireTableCellUpdated()去掉,运行...OK!!