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

fly*_*yer 12 java swing taskbar suse fullscreen

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

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

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

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

BRP*_*ock 18

应该能够"真正全屏" GraphicsDevice.setFullScreenWindow (window).但是,由于最流行的Java运行时中的错误,这可能无法在1.6 = Java 6系列中运行某些"损坏"版本的系统上运行.我没有彻底测试过这个问题,所以补丁可能还没有传播给普通民众.

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

背景/理论

好的,所以这里有太多的信息,而且没有足够的帮助...这里有一些为什么这不起作用...

没有Linux桌面

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

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

您的程序将是X客户端.它可以请求 - 但不是要求 - 在屏幕上放置某个位置或特定大小.各种窗口管理员更多(或更少)倾向于为您提供您想要的东西.

除此之外,大多数桌面玩得很好 (有时候)

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

(超简化:)通常,屏幕的一个或多个边缘上会有面板.通常,顶部只有一个,但有很多变化.这些面板区域不被视为"屏幕的一部分",因此窗口管理器会告诉您的应用程序,"不,这不在您允许玩的区域之外; 这个屏幕不是1920×1080,它只有1890×1080."当然,这可能与您编写应用程序时的预期完全不同,而且您可能在我的上网本上使用800×的物理屏幕480假装只有780×480.

99%的应用程序都很棒.Windows不会妨碍面板,因此您可以随时访问Panel以进行关键控制,例如点击静音或切换到其他程序.

这些"提示"允许您请求您的顶级窗口得到特殊处理.例如,您可以请求没有标题栏 - 或缩小的"调色板"类型标题栏; 您可以请求跳过窗口列表或任务栏或活动概述或可能用于显示活动窗口的任何其他界面; 或者,你可以要求真正全屏,并推动所有其他方式,甚至面板.

规范在这里: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对象......等等)并设置正确的窗口提示,自己.

是的,这很重要......


smi*_*n62 9

只是对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;
}
Run Code Online (Sandbox Code Playgroud)

此致,Stéphane.


bgr*_*nks 6

我意识到这个问题有点陈旧,但我偶然发现它寻找同样的答案.

经过大量的实验,我想出了一个很好的解决方案:

GraphicsDevice d = GraphicsEnvironment
    .getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (d.isFullScreenSupported()) {
    frame.setUndecorated(true);
    frame.setResizable(false);
    frame.addFocusListener(new FocusListener() {

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

        @Override
        public void focusLost(FocusEvent arg0) {
            frame.setAlwaysOnTop(false);
        }
    });
    d.setFullScreenWindow(frame);
} else {
    frame.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)

焦点监听器是这样的,用户可以在窗口外ALT-TAB或META-D,而不会立即强制重新聚焦.

这适用于我使用KDE 4的Linux Mint 15系统.我也使用NVIDIA X-Server.

希望这可以帮助!让我知道它是否也适合你们!