调用alist方法触发EventDispatchThread异常,求Java Swing解决方案
问题排查与解决方案
核心问题分析
- 数组初始化时机错误:Loan类中
amtlist作为成员变量在类加载阶段初始化,此时duration是默认值0,导致数组长度仅为0+1=1。后续alist()方法中循环到用户传入的真实duration+1值时,必然触发ArrayIndexOutOfBoundsException,该异常在Swing事件线程(EventDispatchThread)中抛出,就表现为你遇到的异常。 - 未初始化的
inst变量:alist()方法直接使用inst变量,但inst仅在调用instalment()后才会赋值,若未提前调用,inst为0会导致计算结果错误。
具体修复步骤
1. 修正amtlist的初始化时机
将amtlist的初始化移到构造函数中,确保使用用户传入的真实duration值:
public class Loan { float lamt, irate, inst, lbalance; int duration, nop; String amtlist[][]; // 仅声明,不提前初始化 Loan(float lamt, float irate, int duration, int nop) { this.lamt = lamt; this.irate = irate; this.duration = duration; this.nop = nop; this.amtlist = new String[duration + 1][5]; // 构造函数中用真实duration初始化数组 } // 其余方法保留... }
2. 确保inst在alist()中被初始化
在alist()方法开头调用instalment(),避免使用未赋值的inst,同时优化循环内的重复计算:
public void alist() { instalment(); // 提前初始化inst变量 amtlist[0][0] = "0" ; amtlist[0][1] = "0"; amtlist[0][2] = "0"; amtlist[0][3] = "0"; amtlist[0][4] = Float.toString(inst * annuity(duration, irate)); float v = 1 / (1 + irate); for (int i = 1; i < duration + 1; i++) { amtlist[i][0] = Float.toString(i); amtlist[i][1] = Float.toString(irate * annuity(duration + 1 - i, irate)); amtlist[i][2] = Float.toString(inst); // 直接用已初始化的inst,避免重复计算 amtlist[i][3] = Double.toString(inst * Math.pow(v, i)); amtlist[i][4] = Float.toString(inst * annuity(duration - i, irate)); } }
3. 优化Swing线程安全(可选)
如果AmTable是Swing组件,建议用SwingUtilities.invokeLater包裹创建逻辑,确保组件操作在事件线程中执行:
if (e.getSource() == b2) { l.alist(); fscr.dispose(); SwingUtilities.invokeLater(() -> new AmTable(l.amtlist)); }
需导入javax.swing.SwingUtilities包。
验证修复
完成上述修改后,点击b2按钮时,amtlist会被正确初始化,不会出现数组越界异常,inst变量也会提前赋值,AmTable能正常接收正确的数组数据。
内容的提问来源于stack exchange,提问作者Galaxylokka
相关产品推荐
相关产品推荐

