始终置顶窗口

10

我正在寻找一种方法来保持JFrame始终处于最顶层,而且当我说始终时,我的意思是始终。

setAlwaysOnTop( true );

当我在全屏模式下启动游戏时,这种方法不起作用。我知道通常情况下你不希望窗口保持在最上面,但在这种情况下是必需的。


2
始终置于最顶层,而且“始终”真的是指始终。 即使有两个这样的窗口? - Mark Byers
这个应用程序只会有一个实例在运行。使用“always”这个词只是想表达全屏的应用程序(如游戏)不应该隐藏这个窗口,而全屏的窗口应该仍然可见(在后台)。 - user238801
在一个多窗口系统中,任何时候只能有一个窗口处于最前端(就像《不死战神》中最终只能留下一个人一样)。因此,置顶的要求充其量只是一个请求,无法保证被满足。而全屏应用程序则将置顶提升到了另一个层次——“我希望始终置顶并且完全独占显示”,它的始终置顶权益胜过了你的始终置顶。 - Lawrence Dol
8个回答

4

这是无法完成的。

例如,即使将 Windows 任务管理器设置为始终置顶,也会被全屏应用程序覆盖。

这是因为全屏应用程序通常使用不同的图形上下文,无法叠加显示。


在Windows 8上有一个奇怪的行为(如果算的话),即使窗口被设置为始终置顶,它们甚至会出现在游戏之上(我认为这是一种特性而不是bug)。 - Daniel Sharp

2

启动另一个进程来检查窗口是否在顶部,如果不是,则将其置于顶部。


怎么做?你能提供一个示例链接吗? - pinkpanther

1

这是一个示例代码,应该会有所帮助

public class AllWaysOnTop extends JFrame implements WindowListener {

    AllWaysOnTop() {
        // Code to setup your frame
        addWindowListener(this);
        // Code to show your frame
    }

    // The window event handlers. We use WindowDeactivated to
    // try and keep the splash screen on top. Usually only keeps
    // the splash screen on top of our own java windows.
    public void windowOpened(WindowEvent event){};
    public void windowActivated(WindowEvent event){};
    public void windowDeactivated(WindowEvent event){
        toFront();
    }
    public void windowIconified(WindowEvent event){};
    public void windowDeiconified(WindowEvent event){};
    public void windowClosed(WindowEvent event){};
    public void windowClosing(WindowEvent event) {};
}

参考 此论坛帖子


当一个新的应用程序将以全屏模式启动时,它应该停用此框架。在停用时,我们将其置于前台。从技术上讲应该是可行的。让我试试看。 - Tasawer Khan
那么全屏应用程序会被踢出并最小化自己,对吧?我认为OP正在寻找一种方法,使他的窗口显示在全屏应用程序前面。 - Ben S
是的,您说得对。Layne 没有明确提到这一点,但它会像您所说的那样运作。 - Tasawer Khan
本,你是对的,全屏窗口应该仍然可见,而不是最小化。 - user238801

1

这听起来像是 Raymond Chen 经常需要在 链接 上回答的问题。如何真正永远让一个窗口保持在前景?你无法做到。因为如果其他人的窗口也使用了相同的技巧来始终保持在前景,那么哪个窗口会取胜呢?


0

如果您指的是像DirectX/OpenGL等全屏幕,我不确定您是否能够(或应该)真正实现它。大多数操作系统在全屏模式下禁用其本机窗口以提高渲染性能。Swing通过本机窗口工具包运行。

您可以编写一个使用计时器并在短时间间隔(例如200毫秒)内指示窗口置顶的程序。根据您的操作系统,这可能正是您所需要的,也可能会导致性能问题或闪烁。


1
是的,计时器的想法肯定会导致可怕的闪烁! - mcandre

0

我不确定,但我敢打赌全屏窗口也设置了“始终置顶”,如果是这样,你就进入了未定义行为的领域。一般来说,当两个窗口都设置为始终置顶时,它们之间的顺序是没有保证的。我认为一般情况下,顺序只取决于它们被设置为始终置顶的顺序。所以在这种情况下,我会等到应用程序进入全屏模式后再将其设置为始终置顶,看看是否有效。

在其他情况下,我见过人们启动线程,然后偶尔重置框架为始终置顶。

所有这些解决方案都很丑陋,所以请使用让您晚上能够安心睡觉的方法。


0

我知道这篇文章已经有些年头了,但是我也遇到了这个问题,并且找到了一个令人满意的解决方案。 我的程序有一些通知,我希望它们始终保持在最上层,但是当电影进入全屏模式时,它们就会消失。幸运的是,我的程序每5秒钟更新一次这些通知,如果我在这些JWindows上调用setVisible(true),在每次更新时,它们就会重新获得最上层的位置,如果它们失去了它。


-1

我想做和 OP 一样的事情,让我的应用在前台运行而我的游戏也在运行。但是如果你把游戏放到窗口模式并调整窗口设置以适应你的电视,它就可以工作了,但全屏不行。我只需要使用 frame.setAlwaysOnTop 就可以让它工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接