You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing开发井字棋使用ActionListener出现数组越界报错

问题根因

你遇到的是Java lambda表达式的变量捕获特性导致的问题:

  • 循环中注册监听器用的lambda e -> knappar[i].setEnabled(false) 没有捕获循环执行到当前步时的i值,而是捕获了i变量本身的引用
  • 你的i是Fenster类的成员变量,9次循环结束后i已经自增到9,点击按钮触发lambda执行时,读取的就是此时值为9的i,访问knappar[9]自然超出了长度为9的数组边界。
修复方案

方案1:循环内新增临时变量存储当前索引

在while循环内部定义一个final修饰的临时变量存储当前的i值,lambda中用这个临时变量替代i即可:

while(i <= 8) {
    final int currentIdx = i; // 新增行,存储当前循环的索引
    knappar[i].setBounds(b, h, 100, 100);
    knappar[i].setLayout(null);
    knappar[i].addActionListener(e -> knappar[currentIdx].setEnabled(false)); // 替换为currentIdx
    knappar[i].setBackground(Color.green);
    this.add(knappar[i]);
    
    if (i%2 == 0) {
    }
    
    b = b+110;
        
    if(b > 230) {
        b = 10;
        h =h+110;
    }
    i++;
}

每次循环生成的currentIdx都是独立的不可变变量,不会随后续i的自增改变,lambda捕获到的就是对应按钮的正确索引。

方案2:直接从事件对象获取被点击的按钮

不需要依赖索引定位按钮,直接从事件的源对象获取被点击的组件,从根源避免索引越界问题:

knappar[i].addActionListener(e -> {
    JButton clickedButton = (JButton) e.getSource();
    clickedButton.setEnabled(false);
});

这个方案逻辑更简洁,也不需要额外处理索引变量。

内容的提问来源于stack exchange,提问作者Dava222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:48:03