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

发布于 2024-12-26 11:22:24 字数 533 浏览 1 评论 0原文

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

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

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

在这两种情况下,我的应用程序上都可见 Linux 任务栏。一定是与系统设置/配置有关吗?

I have a problem to run Java application in full screen mode on "openSUSE 11.4 (x86_64)". I am using Java 1.6.0_26-b03.

I have try to run two examples of full screen application:

  1. Example from Oracle site: Display Mode Test.
  2. JDarkRoom.jar (simple text editor) downloaded from Codealchemists.

In both cases I have a Linux Task bar visible over the application. It must be something with system settings/configuration?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆离笙 2025-01-02 11:22:24

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

https://bugs.java.com/bugdatabase/view_bug?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 不会妨碍面板,因此您始终可以通过面板进行关键控制,例如按“静音”或切换到另一个程序等。

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

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

是的,这太恶心了……

You should be able to go “really full screen” with GraphicsDevice.setFullScreenWindow (window). However, due to bugs in the most popular Java runtimes, this may not work on systems running certain “broken” versions in the 1.6 = Java 6 series. I haven't tested this thoroughly, so it may be that the patch hasn't propagated out to the general populace, yet.

https://bugs.java.com/bugdatabase/view_bug?bug_id=7057287

Background/Theory

OK, so here goes for too much information, and not enough help… Here's a bit of why this didn't work right…

There is no Linux Desktop

Linux-based operating systems on PC-type machines, as well as other Unices (with a partial exception for MacOSX), normally use the X Window System (aka X11). Under X, you have an X Server (usually, something kinda like a “video driver”) and clients that connect to it, more often than not, from the same machine (loopback).

The layout and placement of windows is controlled by a special client program, called the Window Manager. It's responsible for decorating the windows (e.g. drawing title bars or resize handles) and positioning them.

Your program would be an X client. It can request — but not demand — placement on the screen at a certain position, or a certain size. Various Window Managers are more (or less) prone to giving you what you want.

Except, most desktops play nicely (sometimes)

Now, by far, most Linux desktops use the Gnome Desktop, with a strong second place for the K Desktop, and a few others are in fairly wide use. What's “nice” is that both of these desktop environments (as well as some others, like XFCE for low-end PC's) conform to the FreeDesktop.org Window Manager Hints standards.

(Super-over-simplification:) Typically, there will be Panels on one or more edges of the screen. Usually, there's just one, across the top, but there are many variations. These Panel areas are not considered “part of the screen,” so the Window Manager tells your application, “no, that's outside of the area in which you're allowed to play; this screen is not 1920×1080, it's only 1890×1080.” Of course, that could be totally different arrangement than what you'd anticipated when you wrote your app, and you might be on my netbook with a physical screen of 800×480 pretending to be only 780×480.

For 99% of apps, that's great. Windows don't get in the way of the Panels, so you can always reach the Panel for critical controls, like hitting Mute or switching to another program or something.

These “hints” allow you to request that your top-level windows get treated specially. For example, you can request that you get no title bar — or a reduced, “palette” type title bar; you can request to be skipped on the window list or task bar or activities overview or whatever other interface might be used to show the active windows; or, you can request to go really full-screen, and push everything else out of the way, even panels.

The spec is here: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html

And the Fail:

Basically, the window manager hints specification wasn't being followed correctly by Sun/Oracle (or Red Hat, who copied off Sun/Oracle, or probably IBM, because they probably did the same, but I don't see anybody complaining about them)…

Although, I do see some griping back and forth about whether it's a bug (specifically) with the K Desktop Environment's window manager (KWin), as apparently this bug only shows up in K, and not in Gnome, XFCE, and friends.

Work-Around

Aside from patching your Java runtimes (and/or your customers'), the only real fix would be to use the platform-specific Java libraries (perhaps grab the underlying AWT objects using reflection… eww…) and set the proper window hints, yourself.

Yes, that's gross…

冰火雁神 2025-01-02 11:22:24

只是对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。

Just a precision on the method of bgroenks:
It's work fine with java7 and java8 on Ubuntu 14.10 (Unity).

BUT: You must set frame.setResizable(true); otherwise, it won't work.

Be careful: the fullscreen mode only works with JFrame (no JDialog or JWindow).

Here a sample code:
It takes place of 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;
}

Regards, Stéphane.

挽心 2025-01-02 11:22:24

我意识到这个问题有点老了,但我偶然发现它寻找相同的答案。

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

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。

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

I realize this question is a bit old, but I stumbled upon it looking for the same answer.

After a lot of experimenting, I came up with a good solution:

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

The focus listener is so the user can ALT-TAB or META-D out of the window without it immediately forcing re-focus.

This works on my Linux Mint 15 system with KDE 4. I am also using a NVIDIA X-Server.

Hope this helps! Let me know if it works for you guys too!

一场春暖 2025-01-02 11:22:24

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

None of the above worked for me, I'm using XUbuntu, But I just tried using a JWindow instead of a JFrame and it worked! That was so frustrating, hopefully it works for you. Oh I should mention I haven't looked at the API yet and I'm really not familiar with the JWindow class so I'm not sure exactly what the differences are between a JWindow and a JFrame. Good luck.

一身骄傲 2025-01-02 11:22:24

我使用全屏模式使用 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();

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

I've used Oracle Java editions 1.6.0_31 and 1.6.0_26 using full screen
mode. I experienced some of the troubles with the window not showing above the taskbar on Ubuntu. However I was able to make it work with this little code sample.

// 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();

The trick that worked is making the window visible first, then placing the window in full screen mode. Setting full screen mode before it's shown resulted in the task bar above the window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文