Java无法捕获AWT-EventQueue-0线程抛出的JFreeChart相关IndexOutOfBoundsException
根本原因
你编写的try-catch仅能捕获当前执行线程下try代码块范围内抛出的异常。从异常栈可以明确看到,报错发生在AWT-EventQueue-0线程(Swing的事件调度线程EDT),异常是JFreeChart异步执行图表重绘逻辑时触发的,和你执行添加/删除XYSeries的线程、代码段完全不在同一个执行上下文,所以你写的catch自然无法捕获到该异常。
解决方案
方案1:从根源避免异常(最推荐)
从逻辑上杜绝越界问题的产生,不需要额外做异常捕获:
- 所有和Swing控件、JFreeChart绑定数据集相关的修改操作,统一放到EDT线程执行,避免多线程并发修改导致数据集状态和绘制逻辑不一致
- 删除XYSeries前先判断
XYSeriesCollection.getSeriesCount()的大小,确认目标序列存在再执行删除操作 - 清空数据集时优先调用
XYSeriesCollection.removeAllSeries(),不要手动按索引删除,避免人为计算索引出错
方案2:设置EDT全局未捕获异常处理器
如果需要统一捕获所有EDT线程抛出的未处理异常,可以在程序初始化阶段添加如下配置:
SwingUtilities.invokeLater(() -> { Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> { // 此处可以捕获所有EDT线程的未处理异常,包括你遇到的IndexOutOfBoundsException throwable.printStackTrace(); System.exit(-1); }); });
方案3:重写ChartPanel的绘制方法加捕获
你也可以自定义ChartPanel子类,在绘制逻辑外层包裹异常捕获:
public class SafeChartPanel extends ChartPanel { public SafeChartPanel(JFreeChart chart) { super(chart); } @Override protected void paintComponent(Graphics g) { try { super.paintComponent(g); } catch (Exception e) { // 捕获所有图表绘制过程中抛出的异常 e.printStackTrace(); System.exit(-1); } } }
把你项目中原有的ChartPanel替换为该自定义类即可。
内容的提问来源于stack exchange,提问作者Barry
相关产品推荐
相关产品推荐

