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

时间:2012-01-12 15:35:30

标签: java swing fullscreen taskbar suse

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

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

  1. Oracle网站示例:Display Mode Test
  2. Codealchemists下载的JDarkRoom.jar(简单文本编辑器)。
  3. 在这两种情况下,我都可以看到应用程序上的Linux任务栏。它必须是系统设置/配置的东西吗?

5 个答案:

答案 0 :(得分: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对象......等等)并设置正确的窗口提示,你自己。

是的,这很糟糕......

答案 1 :(得分:8)

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;
}

此致,Stéphane。

答案 2 :(得分: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);
}

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

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

希望这有帮助!让我知道它是否对你们有用!

答案 3 :(得分:1)

我使用全屏显示Oracle Java版本1.6.0_31和1.6.0_26 模式。我遇到了一些问题,窗口没有显示在Ubuntu上的任务栏上方。但是我能够使用这个小代码示例。

// Create a window for full-screen mode; add a button to leave full-screen mode
GraphicsDevice gs = GraphicsEnvironment.getLocalGraphicsEnvironment().
                    getDefaultScreenDevice(); 
                    //or initialize this for a specific display
Frame frame = new Frame(gs.getDefaultConfiguration());
Window win = new Window(frame);
Canvas c = new Canvas();
c.setBackground(Color.RED);
win.add(c);
win.show();  //or setVisible(true);

// Enter full-screen mode
gs.setFullScreenWindow(win);
win.validate();

有效的技巧是首先使窗口可见,然后将窗口置于全屏模式。在显示之前设置全屏模式会导致窗口上方的任务栏。

答案 4 :(得分:1)

以上都没有为我工作,我正在使用XUbuntu,但我只是尝试使用JWindow而不是JFrame而且它有效!这太令人沮丧了,希望它适合你。哦,我应该提到我还没有看过API,我真的不熟悉JWindow类,所以我不确定JWindow和JFrame之间究竟有什么区别。祝你好运。