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

如何在JFrame中添加3个JPanel实现顶部导航、90%占比主面板及可关闭抽屉

核心问题定位

你当前使用GridLayout作为JFrame根布局,该布局会强制所有子组件平分窗口空间、按行列排列,自然无法实现叠加、分层、抽屉效果,同时没有单独处理背景地图的绘制逻辑。

具体调整步骤
  • 替换JFrame默认内容面板为重写了paintComponent的自定义面板,用来绘制底图的世界地图
  • 根布局改用BorderLayout,顶部放置导航栏(你的buttonPanel),该栏高度自适应即可
  • 中间区域使用JLayeredPane管理分层组件:最底层是透明面板占满中间区域,中间层是带交互按钮的gridPanel(设置半透明或者透明透出背景图),最顶层是抽屉面板,默认隐藏,点击按钮时控制其显示/隐藏
  • 抽屉面板可以固定宽度,放在中间区域的右侧即可
可直接运行的修正代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class TestFrame extends JFrame {
    static JFrame frame;
    static JButton btnExit, btnShowHide;
    static JPanel gridPanel, drawerPanel;
    // 背景图对象,你可以替换为自己的世界地图文件路径
    static Image backgroundImg;

    public static void main(String[] args) {
        // 加载背景图,这里示例用的是本地路径,你可以替换成自己的地图文件
        backgroundImg = new ImageIcon("world_map.png").getImage();

        frame = new JFrame("Main Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 根布局使用BorderLayout
        frame.setLayout(new BorderLayout());

        // ========== 1. 自定义内容面板,绘制背景图 ==========
        JPanel backgroundPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(backgroundImg, 0, 0, getWidth(), getHeight(), this);
            }
        };
        backgroundPanel.setLayout(new BorderLayout());
        frame.setContentPane(backgroundPanel);

        // ========== 2. 顶部导航栏 ==========
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        buttonPanel.setBackground(new Color(255,0,0,180)); // 半透明红色透出背景
        // 退出按钮
        btnExit = new JButton("Exit");
        buttonPanel.add(btnExit);
        btnExit.addActionListener(e -> System.exit(0));
        // 抽屉控制按钮
        btnShowHide = new JButton("show drawer");
        buttonPanel.add(btnShowHide);
        frame.add(buttonPanel, BorderLayout.NORTH);

        // ========== 3. 中间分层区域 ==========
        JLayeredPane layeredPane = new JLayeredPane();
        frame.add(layeredPane, BorderLayout.CENTER);

        // 3.1 中间主面板gridPanel
        gridPanel = new JPanel(new GridLayout(5, 5, 2, 2));
        gridPanel.setOpaque(false); // 透明透出背景图
        gridPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
        placeButtons();
        // 绑定gridPanel尺寸随窗口变化
        layeredPane.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                int width = layeredPane.getWidth();
                int height = layeredPane.getHeight();
                gridPanel.setBounds(0,0,width,height);
                // 抽屉宽度占窗口25%
                drawerPanel.setBounds(width - width/4, 0, width/4, height);
            }
        });
        layeredPane.add(gridPanel, JLayeredPane.DEFAULT_LAYER);

        // 3.2 抽屉面板
        drawerPanel = new JPanel();
        drawerPanel.setBackground(new Color(0,0,255,180)); // 半透明蓝色
        drawerPanel.setVisible(false); // 默认隐藏
        layeredPane.add(drawerPanel, JLayeredPane.POPUP_LAYER);

        // 抽屉按钮事件
        btnShowHide.addActionListener(e -> {
            if(btnShowHide.getText().equals("show drawer")){
                btnShowHide.setText("hide drawer");
                drawerPanel.setVisible(true);
            } else{
                btnShowHide.setText("show drawer");
                drawerPanel.setVisible(false);
            }
        });

        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null); // 窗口居中
        frame.setVisible(true);
    }

    public static void placeButtons(){
        for(int xCnt = 0; xCnt < 5; xCnt++){
            for(int yCnt = 0; yCnt < 5; yCnt++) {
                JButton click = new JButton("x:"+xCnt+" y:"+yCnt);
                // 按钮设置半透明效果
                click.setOpaque(true);
                click.setBackground(new Color(255,255,255,200));
                gridPanel.add(click);
            }
        }
    }
}
使用说明
  • 代码中的world_map.png请替换为你自己的世界地图图片路径即可实现底图效果
  • 抽屉面板默认占窗口宽度的25%,可根据需求调整比例
  • 导航栏、面板都设置了半透明效果,你可以根据需求调整透明度参数(0-255,越大越不透明)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:24:03