【问题标题】:Is there a way to hide the title bar, but keep the buttons in JFrame有没有办法隐藏标题栏,但保留 JFrame 中的按钮
【发布时间】:2020-08-05 22:55:56
【问题描述】:

我想知道是否可以在 Java Swing 中隐藏标题栏,但保留最大化、最小化和关闭按钮。

我尝试添加frame.setUndecorated(true);,但它完全删除了最大化、最小化和关闭按钮。

这是我的代码:

public Display(String title, int width, int height) {
        Display.width = width;
        Display.height = height;

        Display.absWidth = width;
        Display.absHeight = height;

        Display.d = new Dimension(width, height);

        setProperties();

        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        canvas = new Canvas();
        canvas.setPreferredSize(new Dimension(width, height));

        frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        frame.setLayout(new BorderLayout());
        frame.add(canvas, BorderLayout.CENTER);
        frame.setIgnoreRepaint(true);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setResizable(true);

        canvas.createBufferStrategy(2);
        bs = canvas.getBufferStrategy();
        g = bs.getDrawGraphics();

        frame.getRootPane().putClientProperty("apple.awt.fullWindowContent", true);
        frame.getRootPane().putClientProperty("apple.awt.transparentTitleBar", true);

        frame.setVisible(true);

        handleResize();
        handleQuit();

        //showSplashScreen();
    }

【问题讨论】:

    标签: java swing jframe hide titlebar


    【解决方案1】:

    如果要保留本机按钮,则取决于操作系统。

    • Windows:不,您必须使用frame.setUndecorated(true); 并自己复制按钮。这将适用于所有平台,但要获得原生外观,您必须为每个平台单独实现它。
    • macOS:如果您使用 jdk 12 或更新版本,您可以使用:
    rootPane.putClientProperty(“apple.awt.fullWindowContent“, true);
    rootPane.putClientProperty(“apple.awt.transparentTitleBar“, true);
    

    这是取自 jdk 测试用例:

    SwingUtilities.invokeLater(() -> {
        frame = new JFrame("Test");
        frame.setBounds(200, 200, 300, 100);
        rootPane = frame.getRootPane();
        JComponent contentPane = (JComponent) frame.getContentPane();
        contentPane.setBackground(Color.RED);
        rootPane.putClientProperty("apple.awt.fullWindowContent", true);
        rootPane.putClientProperty("apple.awt.transparentTitleBar", true);
        frame.setVisible(true);
    });
    

    请注意,所有 UI 的创建和修改都应使用 SwingUtilities#invokeLaterSwingUtilities#invokeAndWait 在 Swing 主线程上进行。

    您删除标题栏但保留按钮的具体目标是什么?

    【讨论】:

    • 我正在尝试实现类似 CleanMyMac 的窗口。 Example
    • 如果您只针对 macOS,那么使用客户端属性方法是最简单的解决方案。您必须包含一个手动分隔符,这样您的内容就不会被窗口按钮重叠。如果您还针对其他操作系统,您仍然可以在 macOS 上获得相同的解决方案,但您必须确保仅在 macOS 上添加分隔符,并且分隔符本身没有放置重要内容。
    • 您是否将属性添加到 JFrame 或根窗格?您必须使用后者,后者可以通过 JFrame#getRootPane 获得。还要确保您实际上是在 java 13 上运行它。
    • 好吧,没有看到你的其余代码,我不知道为什么它不适合你。你试过用普通的框架吗?
    • 请移除 frame.setIgnoreRepaint(true); 并添加到框架内容窗格 (frame.getContentPane()) 而不是直接添加到框架中。
    猜你喜欢
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    相关资源
    最近更新 更多