You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:15:04