为什么Java Swing的setSize仅在事件监听器中生效,外部调用无效?
问题原因分析
- 核心原因是你的代码中使用了
FlowLayout布局管理器,Swing的布局管理器会自动接管容器内子组件的大小、位置计算逻辑,直接调用setSize设置的绝对大小会被布局管理器覆盖。 - 事件监听器外调用不生效的具体逻辑:你在
frame.setVisible(true)之后调用mapKey.setSize,此时窗口刚完成初始化显示,FlowLayout还会触发一次初始重排逻辑,直接把你刚设置的size值覆盖,所以看起来调用没有生效。 - 事件监听器内临时生效的原因:点击事件触发时,窗口已经完成了初始布局渲染,此时调用
setSize是在布局管理器的常规重排逻辑之后修改的组件属性,短时间内没有新的布局重排触发的话,你设置的大小就会暂时保留。但这个效果是不稳定的,只要窗口发生缩放、移动等会触发布局重排的操作,你设置的大小还是会被布局管理器重置。 - 搭配
setPreferredSize就正常的原因:setPreferredSize是专门提供给布局管理器的参考大小属性,FlowLayout这类标准布局在计算组件大小时,会优先采用组件的preferredSize属性,不会覆盖你设置的这个值,所以只要设置了setPreferredSize,后续每次布局重排都会按照你给定的参考值计算,效果就会稳定生效。
修复方案
把main方法中原有的setSize调用替换为设置首选大小,再触发一次布局重排即可稳定生效,监听器内的setSize也可以同步替换:
// 替换原来的mapKey.setSize调用 mapKey.setPreferredSize(new Dimension(mapKey.getText().length()*9, addMapkey.getPreferredSize().height)); // 触发面板重新计算布局 panel.revalidate(); panel.repaint();
内容的提问来源于stack exchange,提问作者Igor
相关产品推荐
相关产品推荐

