JTabbedPane添加多标签后删除先加标签触发IndexOutOfBoundsException求解
异常原因分析
- 关闭按钮的监听器绑定时机错误且重复绑定:你将
addActionListener逻辑写在了jTabbedPane2MousePressed鼠标点击标签栏的回调里,每次点击标签栏都会给按钮新增一个重复的监听器。当你点击关闭按钮时,多个监听器会依次执行remove操作:第一次执行后标签总数减少,后续监听器再用旧索引执行删除时,自然会出现索引超出当前标签总数的问题。 - 删除索引取值错误:你取的
index是鼠标按下时刻的当前选中标签索引,和你点击的X按钮所属的标签索引不一定一致,且当你删除过标签后,原有标签的索引会整体前移,提前缓存的索引会变成无效的旧值。比如你先加了3个标签(索引0、1、2),删除索引0的标签后,原来的索引1变成0、索引2变成1,此时再用之前缓存的索引2去删除,就会触发你遇到的Index: 2, Tab count: 2报错。 - 按钮引用覆盖问题:从添加标签的代码看
button应该是类成员变量,每次新增标签时都会把button覆盖为最新创建的关闭按钮,导致旧标签的关闭按钮没有正确绑定监听器,只有最后新增的标签的关闭按钮能触发删除逻辑。
修复方案
你应该在创建每个标签的关闭按钮时,就直接绑定对应删除逻辑,不需要依赖全局的选中索引,也不要在鼠标点击标签栏的回调里绑定监听器:
// 把原来写在jTabbedPane2MousePressed里的监听器逻辑移到添加标签的代码中,创建button之后直接加 button.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { // 直接从按钮所属的自定义标签头出发,找到对应标签索引,不用提前缓存index int currentIndex = jTabbedPane2.indexOfTabComponent(pnlTab); if (currentIndex != -1) { jTabbedPane2.remove(currentIndex); } } }); // 同时删除jTabbedPane2MousePressed方法里所有绑定监听器的代码即可
内容的提问来源于stack exchange,提问作者kim2002
相关产品推荐
相关产品推荐

