Java Swing中如何向单个JScrollPane添加多个JPanel?
问题根因
- 你自定义绘制的两个
JPanel没有显式设置首选尺寸,Swing布局管理器默认会给它们分配0x0的显示空间,绘制的内容自然不可见 JPanel默认是不透明的,叠放时上层面板会完全遮挡下层面板的内容- 用AWT原生
Container作为JScrollPane的视图容器,会存在Swing轻量级组件兼容问题
修复方案
直接修改以下几点即可正常显示:
- 将承载两个面板的中间容器从
Container改为JPanel,适配Swing滚动视图的组件规范 - 给两个自定义绘制的
JPanel设置足够覆盖绘制内容的首选尺寸,同时设置为透明避免层叠遮挡 - 你当前使用的
SpringLayout可以保留,如果仅需要两个面板完全叠放,也可以改用更简单的OverlayLayout,不影响最终效果
修复后完整可运行代码如下:
import javax.swing.*; import java.awt.*; public class Test { public static void main(String[] args) { // Swing组件初始化官方要求放在事件调度线程,避免渲染异常 SwingUtilities.invokeLater(() -> new Test()); } public Test() { JFrame frame = new JFrame("Test"); frame.setSize(500, 500); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel base = new JPanel(); SpringLayout baseLayout = new SpringLayout(); base.setLayout(baseLayout); JPanel panel1 = new JPanel() { public void paintComponent(Graphics tool) { super.paintComponent(tool); tool.drawRect(50, 50, 100, 100); } }; // 设置面板首选尺寸、开启透明 panel1.setPreferredSize(new Dimension(200, 200)); panel1.setOpaque(false); JPanel panel2 = new JPanel() { public void paintComponent(Graphics tool) { super.paintComponent(tool); tool.drawRect(75, 75, 50, 50); } }; // 设置面板首选尺寸、开启透明 panel2.setPreferredSize(new Dimension(200, 200)); panel2.setOpaque(false); // 改用JPanel作为承载两个子面板的中间容器 JPanel cont = new JPanel(); SpringLayout contLayout = new SpringLayout(); cont.setLayout(contLayout); contLayout.putConstraint(SpringLayout.WEST, panel1, 0, SpringLayout.WEST, cont); contLayout.putConstraint(SpringLayout.NORTH, panel1, 0, SpringLayout.NORTH, cont); cont.add(panel1); contLayout.putConstraint(SpringLayout.WEST, panel2, 0, SpringLayout.WEST, cont); contLayout.putConstraint(SpringLayout.NORTH, panel2, 0, SpringLayout.NORTH, cont); cont.add(panel2); cont.setPreferredSize(new Dimension(201, 201)); JScrollPane scroll = new JScrollPane(cont); scroll.setPreferredSize(new Dimension(200, 200)); baseLayout.putConstraint(SpringLayout.HORIZONTAL_CENTER, scroll, 0, SpringLayout.HORIZONTAL_CENTER, base); baseLayout.putConstraint(SpringLayout.VERTICAL_CENTER, scroll, 0, SpringLayout.VERTICAL_CENTER, base); base.add(scroll); frame.add(base); frame.setVisible(true); } }
如果你需要两个面板非叠放排列,比如上下/左右排布,直接把中间容器cont的布局改为BoxLayout或GridLayout即可,不需要手动设置布局约束。
内容的提问来源于stack exchange,提问作者LuckyBandit74
相关产品推荐
相关产品推荐

