Swing调用setBackground触发StackOverFlow递归错误的解决方法
问题根因
- 无限递归触发栈溢出:你写的
panel()方法中,panel().setBackground(Color.cyan)这行代码没有操作你刚创建的JPanel实例,而是再次调用了panel()方法自身,形成无限递归,调用栈持续膨胀最终抛出StackOverflowError,和setBackground本身无关。 - 工具方法逻辑错误:你现有的
frame()、mainPanel()、panel()、constr()方法每次被调用都会返回全新的对象,你在AddWindow中多次调用这些方法时,所有的约束配置、组件添加操作都是在不同的实例上执行的,就算解决栈溢出问题,最终渲染的界面也不会显示你添加的组件。
修复代码
修改工具类方法
将工具方法改为成员变量缓存实例,同时删掉递归调用,直接操作新创建的对象:
// 增加成员变量缓存实例,避免重复创建 private JFrame frame; private JPanel mainPanel; private JPanel gridPanel; private GridBagConstraints constr; public JFrame frame(){ if(frame == null) { frame = new JFrame(); frame.setTitle("a new " + MethodHandles.lookup().lookupClass().getName() + " Appears! "); } return frame; } public JPanel mainPanel(){ if(mainPanel == null) { mainPanel = new JPanel(); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); // 直接操作当前实例,不要调用mainPanel() mainPanel.setBackground(Color.cyan); } return mainPanel; } public JPanel panel(){ if(gridPanel == null) { gridPanel = new JPanel(new GridBagLayout()); // 直接操作当前实例,不要递归调用panel() gridPanel.setBackground(Color.cyan); } return gridPanel; } public GridBagConstraints constr(){ if(constr == null) { constr = new GridBagConstraints(); } return constr; }
调用逻辑无需修改
修改工具类后,你原有AddWindow方法里的调用逻辑可以完全保留,因为现在每次调用OPT.frame()、OPT.panel()等方法都会返回同一个实例,所有配置和组件添加操作都会生效。
背景设置说明
不需要额外新建单独的面板设置背景,修复递归问题后,你可以直接给需要的面板实例设置背景色即可,不会再触发栈溢出。
内容的提问来源于stack exchange,提问作者Bispar426
相关产品推荐
相关产品推荐

