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

Java Swing实现JFrame同一JScrollPane内两个JPanel并排显示

问题根因
  • JScrollPane的滚动视图区(Viewport)仅支持承载单个组件,直接调用scrollPane.add(consolePanel)是把组件加到滚动面板的非视图层(滚动条、角落组件预留层),不会显示在滚动区域内。
  • 直接调用this.add(consolePanel)时,JFrame默认使用的BorderLayout会把无约束的组件放到CENTER区域,和原有的scrollPane抢占布局位置,同一个布局位置添加多个组件就会出现渲染错乱。
实现方法

新增一个中间JPanel容器作为JScrollPane视图区的唯一组件,使用水平排列的布局将MapPanel和ConsolePanel按顺序添加到这个中间容器中,再把中间容器设置为滚动面板的视图内容即可实现两个面板并排、同区域滚动的效果。

修改后的MapFrame核心代码

public class MapFrame extends JFrame{
    public MapFrame() {
        buildTheUI();
        setUpEventHandling();

        mapPanel = new MapPanel();
        ConsolePanel consolePanel = new ConsolePanel();
        // 给控制台面板设置初始尺寸
        consolePanel.setPreferredSize(new Dimension(400, mapPanel.getPreferredSize().height));
        // 如果需要固定控制台宽度不被布局压缩,放开下面两行注释
        // consolePanel.setMinimumSize(consolePanel.getPreferredSize());
        // consolePanel.setMaximumSize(consolePanel.getPreferredSize());

        // 创建承载两个面板的中间容器
        JPanel scrollContent = new JPanel();
        // 设置水平排列布局
        scrollContent.setLayout(new BoxLayout(scrollContent, BoxLayout.X_AXIS));
        scrollContent.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        // 按顺序添加组件,中间留10px空隙
        scrollContent.add(mapPanel);
        scrollContent.add(Box.createHorizontalStrut(10));
        scrollContent.add(consolePanel);

        JScrollPane scrollPane = new JScrollPane();
        // 将中间容器设置为滚动面板的视图内容
        scrollPane.setViewportView(scrollContent);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        this.setLayout(new BorderLayout());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(1024, 1024);
        // 明确指定滚动面板放到BorderLayout的CENTER区域占满窗口
        this.add(scrollPane, BorderLayout.CENTER);
        this.pack();
        this.setVisible(true);
    }
}

ConsolePanel优化修正

原有代码复用同一个GridBagConstraints对象会导致布局约束异常,调整为每个组件单独设置约束,同时让文本区自动占满面板剩余空间:

public class ConsolePanel extends JPanel {
    public ConsolePanel(){
        this.setLayout(new GridBagLayout());
        // 通过行列数定义文本区初始尺寸,比直接setPreferredSize更适配不同系统的字体渲染
        TextArea console = new TextArea("random info here", 25, 40);
        console.setEditable(false);

        // 控制台标题约束
        GridBagConstraints titleCons = new GridBagConstraints();
        titleCons.gridx = 0;
        titleCons.gridy = 0;
        titleCons.anchor = GridBagConstraints.WEST;
        titleCons.insets = new Insets(0,0,5,0);
        this.add(new JLabel("Console"), titleCons);

        // 文本区约束
        GridBagConstraints textCons = new GridBagConstraints();
        textCons.gridx = 0;
        textCons.gridy = 1;
        textCons.weightx = 1.0;
        textCons.weighty = 1.0;
        textCons.fill = GridBagConstraints.BOTH;
        this.add(console, textCons);
    }
}
注意事项
  • 不要直接调用JScrollPane.add()添加业务组件,该方法仅用于添加滚动面板自身的内部控件(滚动条、角标等),业务内容必须通过setViewportView()设置到视图区。
  • 使用BorderLayout时,建议给所有添加的组件明确指定布局约束(比如BorderLayout.CENTER/BorderLayout.EAST),避免默认位置导致的布局覆盖问题。

内容的提问来源于stack exchange,提问作者Mr.Gomer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:15:30