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

JFrame游戏开发:首循环内Button.setEnabled失效问题

问题分析与修复方案

我一眼就看出问题出在你循环里的按钮状态重置逻辑上!咱们先看第一个检查行的循环:你在每次循环的else分支里都执行confirm.setEnabled(true),这就导致了一个致命问题——哪怕前面已经检测到重复并禁用了按钮,只要后面有一个不重复的元素,按钮就会被重新启用。比如假设行里第2个元素和目标重复,你设置了禁用,但循环到第3个元素时,因为不匹配,又把按钮改回启用状态,最后按钮还是亮的,这就是你觉得“首循环无法禁用”的原因。

其他循环看起来能正常工作,大概率是因为你测试时重复元素刚好在循环的最后一个位置,这时else不会触发,按钮保持禁用状态,但这只是巧合,逻辑本身是错的。

修复后的代码

private void checkRepetitions() {
    boolean check = false;
    int i, j;
    // 先默认按钮是启用状态,只有检测到重复才禁用
    confirm.setEnabled(true);
    
    // 检查行
    i = lastI;
    for (j = 0; j < 8; j++) {
        // 先判断文本不为空,再比较,避免空字符串干扰
        String targetText = tab[lastI][lastJ].getText();
        if (!targetText.isEmpty() && lastI != j && targetText.equals(tab[i][j].getText())) {
            confirm.setEnabled(false);
            check = true;
            break; // 找到重复就跳出循环,不用继续检查
        }
        // 这里不需要else分支,默认已经是启用状态了
    }
    
    // 如果已经检测到重复,后面的检查可以直接跳过,提升效率
    if (check) return;
    
    // 检查列
    j = lastJ;
    for (i = 0; i < 8; i++) {
        String targetText = tab[lastI][lastJ].getText();
        if (!targetText.isEmpty() && lastI != i && targetText.equals(tab[i][j].getText())) {
            confirm.setEnabled(false);
            check = true;
            break;
        }
    }
    
    if (check) return;
    
    // 检查主对角线(左上到右下)
    if (lastJ == lastI) {
        i = 0;
        j = 0;
        while (i < 8 && j < 8) { // 原条件i<7&&j<7会漏掉最后一个元素,修正边界
            String targetText = tab[lastI][lastJ].getText();
            if (!targetText.isEmpty() && lastI != i && targetText.equals(tab[i][j].getText())) {
                confirm.setEnabled(false);
                check = true;
                break;
            }
            i++;
            j++;
        }
    }
    
    if (check) return;
    
    // 检查副对角线(右上到左下)
    if (lastI + lastJ == 7) {
        i = 0;
        j = 7;
        while (i < 8 && j >= 0) {
            String targetText = tab[lastI][lastJ].getText();
            if (!targetText.isEmpty() && lastI != i && lastJ != j && targetText.equals(tab[i][j].getText())) {
                confirm.setEnabled(false);
                check = true;
                break;
            }
            i++;
            j--;
        }
    }
}

关键修改点说明

  • 默认状态初始化:把confirm.setEnabled(true)放在方法开头,这样只有检测到重复时才会修改为禁用,避免循环中反复重置状态。
  • 移除循环内的else分支:不再在每次不匹配时重置按钮状态,确保一旦检测到重复,按钮保持禁用。
  • 提前终止检查:每次检测到重复后设置check=true,然后用return跳过后续的检查,提升代码效率。
  • 修正循环边界:原对角线循环的条件会漏掉最后一个元素,调整后确保检查覆盖所有位置。
  • 调整判断顺序:先判断文本是否为空,再进行相等比较,避免空字符串误判,也让逻辑更清晰。

这样修改后,不管重复元素出现在行、列还是对角线的哪个位置,只要检测到重复,confirm按钮就会被正确禁用,不会被后续的循环步骤重置。

内容的提问来源于stack exchange,提问作者D.Weltrowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:08:41