Scanner读JFileChooser选中文本生成二维int数组的GUI异常问题
原代码卡死与逻辑错误定位
- 致命死循环阻塞GUI:代码中
while (reader.hasNextInt()) { size++; }没有任何实际的读取操作。由于目标文本每行是连续无分隔的数字串(如000000),Scanner会持续判定hasNextInt()为true,永远无法跳出循环,直接堵死Swing事件调度线程,最终表现为界面无响应、窗口无法关闭。 - 读取逻辑不符合需求:使用
nextInt()读取连续数字串,会把整行的6个连续0/1当成单个整数加载,完全达不到“每个独立0/1作为数组单个元素”的目标。 - 文件指针错位:在死循环判断的过程中,Scanner的读取指针已经移动到文件末尾,后续用来填充二维数组的读取循环拿不到任何有效数据,无法正确初始化数组。
- 线程使用违规:所有文件解析操作直接在Swing事件调度线程执行,哪怕文件尺寸稍大,也会因为事件队列被阻塞导致界面卡死。
可正常运行的修正实现
实现思路:
- 用
SwingWorker把文件读取、解析逻辑放到后台线程执行,不阻塞界面响应,从根源上解决GUI无响应问题。 - 改用逐行读取方式解析文件,不依赖Scanner的自动token拆分,适配连续无空格的0/1文本格式。
- 用动态列表存储解析完成的行,不需要提前遍历文件计算行列数,天然支持任意行列数的TXT文本。
- 解析时直接通过字符ASCII值转换数字,把行内每个字符转成对应int类型的0/1,避免字符串拆分的性能损耗。
修正后的代码:
File selectedFile = fc.getSelectedFile(); // 后台执行耗时的文件读取操作 SwingWorker<int[][], Void> fileParser = new SwingWorker<>() { @Override protected int[][] doInBackground() throws Exception { // try-with-resources自动关闭文件流 try (BufferedReader br = new BufferedReader(new FileReader(selectedFile))) { List<int[]> parsedRows = new ArrayList<>(); String currentLine; // 逐行读取 while ((currentLine = br.readLine()) != null) { // 可选:跳过文件中的空行 if (currentLine.trim().isEmpty()) continue; int[] row = new int[currentLine.length()]; // 把每个字符转成对应的int数字 for (int col = 0; col < currentLine.length(); col++) { row[col] = currentLine.charAt(col) - '0'; } parsedRows.add(row); } // 转成固定二维数组返回 return parsedRows.toArray(new int[0][]); } } @Override protected void done() { try { // 读取完成后回到事件调度线程,拿到解析好的二维数组 int[][] iBoard = get(); // 在这里将数组数据更新到界面组件上 } catch (Exception e) { e.printStackTrace(); // 可添加弹窗提示用户文件读取失败 } } }; fileParser.execute();
补充说明:上述实现没有对行列长度做任何固定限制,只要文本是由连续的0/1组成的行,就能正确解析;文件流会在读取完成后自动释放,不需要手动调用close方法;界面操作全部回到事件调度线程执行,完全符合Swing的线程规范。
内容的提问来源于stack exchange,提问作者Stonezarcon
相关产品推荐
相关产品推荐

