JScrollPane内垂直放置JPanel异常及paintComponent失效问题求助
问题根因
- JScrollPane仅支持单个视口组件作为滚动内容,直接调用
JScrollPane.add()添加多个SlideView的写法不符合ScrollPaneLayout的布局规则,会导致组件堆叠、无法正常渲染,自定义paintComponent方法也不会被触发。 - 垂直排列的BoxLayout绑定位置错误,原本需要在滚动区域内垂直排列的SlideView,应该绑定到JScrollPane的内部内容容器上,而非外层的PresentationView。
- SlideView仅配置了最大、最小尺寸,未设置首选尺寸,部分Swing布局管理器会优先读取首选尺寸计算布局,可能导致组件尺寸计算异常。
修复代码
PresentationView类修改后代码
public class PresentationView extends JPanel { private Presentation presentation; private JScrollPane jsp; public PresentationView(Presentation presentation){ this.presentation = presentation; jsp = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); // 新建滚动内容容器,设置垂直BoxLayout JPanel scrollContent = new JPanel(); scrollContent.setLayout(new BoxLayout(scrollContent, BoxLayout.Y_AXIS)); // 所有SlideView添加到内容容器中 for(RuNode s: presentation.getChildren()){ scrollContent.add(new SlideView((Slide) s)); System.out.println(s.getName()); } // 将内容容器绑定到滚动面板视口 jsp.setViewportView(scrollContent); // 外层面板用BorderLayout铺满滚动面板 setLayout(new BorderLayout()); add(jsp, BorderLayout.CENTER); } }
SlideView类修改后代码
public class SlideView extends JPanel { private Slide slide; private Image img; public SlideView(Slide slide){ this(new ImageIcon(((Presentation)slide.getParent()).getImgPath()).getImage()); // 统一配置尺寸规则,避免布局计算偏差 setPreferredSize(new Dimension(400, 400)); setMaximumSize(new Dimension(400, 400)); setMinimumSize(new Dimension(400, 400)); setBackground(Color.PINK); setBorder(BorderFactory.createLineBorder(Color.BLACK, 5)); this.slide = slide; } public SlideView(Image img){ this.img = img; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 增加非空判断避免空指针异常 if (img != null) { g.drawImage(img, (int)(this.getWidth()-img.getWidth(null))/2, (int)(this.getHeight()-img.getHeight(null))/2, null); } } }
内容的提问来源于stack exchange,提问作者Luka Lazarevic
相关产品推荐
相关产品推荐

