Linux上的Java全屏 - 如何覆盖任务栏?

2022-09-04 05:49:45

我在“openSUSE 11.4(x86_64)”上以全屏模式运行Java应用程序时遇到问题。我使用的是Java 1.6.0_26-b03。

我尝试运行两个全屏应用程序的示例:

  1. 来自 Oracle 站点的示例:显示模式测试
  2. JDarkRoom.jar(简单的文本编辑器)从Codealchemists下载。

在这两种情况下,我都有一个在应用程序上可见的Linux任务栏。它必须是具有系统设置/配置的东西吗?


答案 1

您应该能够使用“真正全屏”。但是,由于最流行的Java运行时中的错误,这可能不适用于运行1.6 = Java 6系列中某些“损坏”版本的系统。我还没有对此进行彻底的测试,因此可能该补丁尚未传播给普通大众。GraphicsDevice.setFullScreenWindow (window)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7057287

背景/理论

好吧,所以这里的信息太多了,而没有足够的帮助...以下是为什么这不能正常工作的原因...

没有 Linux 桌面

PC型机器上基于Linux的操作系统以及其他Unices(MacOSX的部分例外)通常使用X Window系统(又名X11)。在X下,你有一个X服务器(通常有点像“视频驱动程序”)和客户端,它们通常从同一台计算机(环回)连接到它。

窗口的布局和位置由一个特殊的客户端程序控制,称为窗口管理器。它负责装饰窗口(例如绘制标题栏或调整大小手柄)并对其进行定位。

您的程序将是一个 X 客户端。它可以请求(但不能要求)放置在屏幕上的特定位置或特定大小。各种窗口管理器或多或少倾向于给你你想要的东西。

除了,大多数台式机玩得很好(有时)

现在,到目前为止,大多数Linux桌面都使用Gnome Desktop,在K Desktop中占有第二的位置,其他一些桌面的使用相当广泛。“好”的是,这两个桌面环境(以及其他一些,如用于低端PC的XFCE)都符合 FreeDesktop.org 窗口管理器提示标准。

(超级过度简化:)通常,屏幕的一个或多个边缘上会有面板。通常,只有一个,在顶部,但有很多变化。这些面板区域不被视为“屏幕的一部分”,因此窗口管理器会告诉您的应用程序,“不,这超出了您可以玩游戏的区域;这个屏幕不是1920×1080,它只是1890×1080。当然,这可能与你编写应用程序时的预期完全不同,你可能在我的上网本上,物理屏幕为800×480,假装只有780×480。

对于 99% 的应用来说,这很棒。Windows不会妨碍面板,因此您始终可以访问面板以获取关键控件,例如按静音或切换到其他程序或其他内容。

这些“提示”允许您请求对顶级窗口进行特殊处理。例如,您可以请求没有标题栏 - 或者减少的“调色板”类型标题栏;您可以请求在窗口列表或任务栏或活动概述或任何其他可用于显示活动窗口的界面上跳过;或者,您可以要求完全全屏显示,并将其他所有内容(甚至是面板)都排除在外。

规格在这里:http://standards.freedesktop.org/wm-spec/wm-spec-latest.html

失败:

基本上,窗口管理器暗示Sun/Oracle(或Red Hat,他们复制了Sun/Oracle,或者可能是IBM,因为他们可能做了同样的事情,但我没有看到任何人抱怨他们)没有正确遵循规范......

虽然,我确实看到一些关于它是否是K桌面环境的窗口管理器(KWin)的错误(特别是)的抱怨,因为显然这个错误只出现在K中,而不是在Gnome,XFCE和朋友中。

解决方法

除了修补您的Java运行时(和/或您的客户的运行时)之外,唯一真正的解决方案是使用特定于平台的Java库(也许使用反射来获取底层AWT对象...哇...)并设置适当的窗口提示,你自己。

是的,这很严重...


答案 2

只是bgroenks方法的精确度:
它在Ubuntu 14.10(Unity)上与java7和java8一起工作得很好。

但是:您必须设置其他设置,否则它将不起作用。frame.setResizable(true);

请注意:全屏模式仅适用于JFrame(没有JDialog或JWindow)。

下面是一个示例代码:它取代了setVisible(true)

/**
 * @param frame
 * @param doPack
 * @return device.isFullScreenSupported
 */
static public boolean fullScreen(final JFrame frame, boolean doPack) {

    GraphicsDevice device = frame.getGraphicsConfiguration().getDevice();
    boolean result = device.isFullScreenSupported();

    if (result) {
        frame.setUndecorated(true);
        frame.setResizable(true);

        frame.addFocusListener(new FocusListener() {

            @Override
            public void focusGained(FocusEvent arg0) {
                frame.setAlwaysOnTop(true);
            }

            @Override
            public void focusLost(FocusEvent arg0) {
                frame.setAlwaysOnTop(false);
            }
        });

        if (doPack)
            frame.pack();

        device.setFullScreenWindow(frame);
    }
    else {
        frame.setPreferredSize(frame.getGraphicsConfiguration().getBounds().getSize());

        if (doPack)
            frame.pack();

        frame.setResizable(true);

        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        boolean successful = frame.getExtendedState() == Frame.MAXIMIZED_BOTH;

        frame.setVisible(true);

        if (!successful)
            frame.setExtendedState(Frame.MAXIMIZED_BOTH);
    }
    return result;
}

问候,斯蒂芬。


推荐