Java JSpinner无法显示内容 仅调整Frame窗口大小时可见问题求助
问题根因
- 窗口可见性设置时机错误:在添加
JSpinner组件前就调用了setVisible(true)完成了窗口首次渲染,后续新增组件后仅调用repaint()无法触发容器的布局重新校验,只有手动调整窗口大小时系统自动触发validate()重算布局,组件才会正常显示。 - 内容面板配置错误:你将内容面板设置为无默认布局管理器的
JLabel,就算组件能渲染也无法按照预期规则排布。 - 不符合Swing线程规范:所有Swing组件的初始化、更新操作都应当在事件调度线程(EDT)中执行,直接在主线程操作会出现偶发渲染异常。
修正方案
调整组件初始化和窗口可见性的设置顺序,使用默认的内容面板或者带布局的容器,将setVisible(true)放到所有组件添加完成之后,同时按Swing规范将窗口初始化逻辑放入EDT执行。
修正后代码
package pack; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; public class Test extends JFrame{ private static final long serialVersionUID = 1L; JSpinner spinner; public Test() { // 先配置窗口基础属性 setSize(500, 500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 移除错误的setContentPane配置,使用默认的JPanel内容面板(默认BorderLayout) // 初始化并添加组件 SpinnerNumberModel model = new SpinnerNumberModel(1, 0, 2, 1); spinner = new JSpinner(model); add(spinner); // 所有组件添加完成后再设置窗口可见 setVisible(true); } public static void main(String[] args) { // 遵循Swing线程规范,在EDT中初始化窗口 SwingUtilities.invokeLater(() -> new Test()); } }
如果确实需要自定义组件大小和位置,可以给内容面板设置空布局setLayout(null),再给JSpinner调用setBounds(x,y,width,height)指定位置和尺寸,该操作同样要在setVisible(true)之前完成。
内容的提问来源于stack exchange,提问作者mousekip
相关产品推荐
相关产品推荐

