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

如何让JScrollPane中可动态调整大小的JPanel正常工作

问题排查与修复方案

核心错误点

  • 给JScrollPane添加内部滚动组件不能调用add()方法,必须调用setViewportView()把组件放到滚动视口中,直接add()的组件不会被滚动逻辑渲染,自然不可见
  • Swing组件只能绑定一个父容器,你初始已经把panel添加到了JFrame中,后续要转移到JScrollPane之前,需要先把它从原父容器中移除
  • 不需要每次点击按钮都重复把JScrollPane添加到JFrame中,初始布局阶段就可以把JScrollPane添加到窗口,仅动态修改内部panel的尺寸即可,反复添加组件会导致层级混乱
  • 空布局(null layout)下修改组件层级或尺寸后,必须调用repaint()触发窗口重绘,否则会出现显示残留

修正后可运行代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Frame extends JFrame implements ActionListener{
    int scrollBarSize;
    JButton button;
    JPanel buttonPanel;
    JPanel panel = new JPanel();
    JScrollPane pane = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JTextField text;
    
    int bigPanelPos = 495, bigPanelSize = 55 , smallPanelPos;

    Frame(){
        this.setSize(700,700);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setLayout(null);
        scrollBarSize = ((Integer)UIManager.get("ScrollBar.width")) + 1;

        pane.setBounds(0,0,700,550);
        // 初始就把滚动面板添加到窗口
        this.add(pane);
        
        panel.setBackground(Color.yellow);
        panel.setBounds(0,495,700,55);
        panel.setAlignmentX(Component.CENTER_ALIGNMENT);
        panel.setAlignmentY(Component.CENTER_ALIGNMENT);

        button = new JButton("Click me!");
        button.setPreferredSize(new Dimension(50,15));
        button.setFont(new Font("Didot",Font.BOLD, 15));
        button.addActionListener(this);
        
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
        buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
        buttonPanel.setAlignmentY(Component.CENTER_ALIGNMENT);
        buttonPanel.setBorder(BorderFactory.createTitledBorder("ButtonPanel"));
        buttonPanel.setBounds(0, 550, 700, 150 );
        buttonPanel.add(button);
        
        this.add(panel);
        this.add(buttonPanel);
        this.setVisible(true);
        
    }
    
    public void actionPerformed(ActionEvent e) {
        
        if (e.getSource() == button) {
            bigPanelPos -= 55;
            bigPanelSize +=55;
            
            int n = scrollBarSize;
            panel.setPreferredSize(new Dimension(700 - n,bigPanelSize));
            // 仅首次点击时转移panel到滚动视口
            if (panel.getParent() != pane.getViewport()) {
                if (panel.getParent() != null) {
                    panel.getParent().remove(panel);
                }
                pane.setViewportView(panel);
            }
            pane.revalidate();
            this.repaint();
            
            System.out.println(pane.getBounds());
            System.out.println(panel.getBounds());
        }
    }

    public static void main(String[] args) {
        new Frame();
    }
}

内容的提问来源于stack exchange,提问作者ItsSilver

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:45:03