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

如何在JFrame标题栏上放置自定义按钮

解决方案

问题根源

默认JFrame的标题栏属于系统级窗口装饰,不归Swing的内容面板管理。你直接添加到JFrame的组件都会被绘制在标题栏下方的客户区域,超出这个区域的部分会被默认裁剪,因此设置负y坐标的按钮会被标题栏遮挡。

实现思路

关闭系统默认窗口装饰,自行实现完整的标题栏UI,就可以自由在标题栏区域放置任意组件了。

修改后可运行代码

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SetBoundsTest {
    // 记录窗口拖动的坐标偏移
    static int dragX, dragY;

    public static void main(String arg[]) {
        JFrame frame = new JFrame("Test Frame");
        frame.setSize(500, 250);
        // 关闭系统默认装饰
        frame.setUndecorated(true);
        frame.setLayout(new BorderLayout());

        // 自定义标题栏面板
        JPanel titleBar = new JPanel(new BorderLayout());
        titleBar.setPreferredSize(new Dimension(frame.getWidth(), 35));
        titleBar.setBackground(Color.LIGHT_GRAY);
        Border border = BorderFactory.createMatteBorder(0, 0, 1, 0, Color.GRAY);
        titleBar.setBorder(border);

        // 标题文字
        JLabel titleLabel = new JLabel(" Test Frame");
        titleBar.add(titleLabel, BorderLayout.WEST);

        // 你要添加的自定义按钮
        JButton customBtn = new JButton("Test");
        customBtn.setBorder(BorderFactory.createLineBorder(Color.BLUE, 3));
        customBtn.setBackground(Color.MAGENTA);
        customBtn.setPreferredSize(new Dimension(120, 30));
        // 放到标题栏中间
        JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 2));
        btnPanel.setOpaque(false);
        btnPanel.add(customBtn);
        titleBar.add(btnPanel, BorderLayout.CENTER);

        // 右上角关闭按钮,模拟系统功能
        JButton closeBtn = new JButton("×");
        closeBtn.setPreferredSize(new Dimension(50, 35));
        closeBtn.setBorderPainted(false);
        closeBtn.setFocusPainted(false);
        closeBtn.setBackground(Color.LIGHT_GRAY);
        closeBtn.addActionListener(e -> System.exit(0));
        // 鼠标悬停变红
        closeBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                closeBtn.setBackground(Color.RED);
                closeBtn.setForeground(Color.WHITE);
            }
            @Override
            public void mouseExited(MouseEvent e) {
                closeBtn.setBackground(Color.LIGHT_GRAY);
                closeBtn.setForeground(Color.BLACK);
            }
        });
        titleBar.add(closeBtn, BorderLayout.EAST);

        // 实现窗口拖动功能
        titleBar.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                dragX = e.getX();
                dragY = e.getY();
            }
        });
        titleBar.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                frame.setLocation(frame.getX() + e.getX() - dragX, frame.getY() + e.getY() - dragY);
            }
        });

        // 把标题栏添加到窗口顶部
        frame.add(titleBar, BorderLayout.NORTH);
        // 剩下的内容区域你可以自己加其他组件
        JPanel contentPane = new JPanel();
        contentPane.setBackground(Color.WHITE);
        frame.add(contentPane, BorderLayout.CENTER);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

效果说明

上述代码完全自定义了标题栏,不仅可以实现你需要的在标题栏中间放置按钮的效果,还保留了窗口拖动、关闭的基础功能,你可以根据自己的需求调整标题栏的样式、按钮的位置和功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:36:03