JavaFX次屏幕“始终置顶”于所有应用程序

6
我了解使用JDialog来包装JFXPanel以使用JDialog的alwaysOnTop方法的技巧。尽管这种方法很有效,但是我在使用此方法时遇到了一个小问题。
由于我使用此技术来创建主应用程序的次要窗口(弹出窗口等),因此需要将它们放置在主窗口之上。如果我使用包装器技巧来实现此操作,则顶部面板将“始终置于最上方”(包括其他应用程序)。
有没有一种方法可以将次要屏幕仅放置在我的应用程序之上?我不喜欢另一个应用程序可以被拖到我的应用程序的主窗口和次要窗口之间的事实。
2个回答

17
我建议不要使用JDialogJFXPanel, 而只使用JavaFX Stages
将你的辅助屏幕设置为Stage,在显示辅助界面之前调用secondaryStage.initOwner(primaryStage)
从Stage文档中可以看到:

一个stage可选地有一个拥有者窗口。当一个窗口是一个stage的所有者时,它被称为该stage的父窗口...一个stage将始终在其父窗口的顶部。

我认为正确设置辅助屏幕的所有者可以满足你“辅助屏幕只在我的应用程序顶部”的要求。

更新:回答了评论中的额外问题

我不希望主舞台与次舞台进行任何交互(必须关闭次窗口才能再次进行交互)。

为了阻止对主舞台的输入,在显示次舞台之前,调用:secondaryStage.initModality(Modality.WINDOW_MODAL)

您可以使用APPLICATION_MODAL而不是WINDOW_MODAL,如果您更喜欢阻止对应用程序的任何其他窗口的所有输入-要使用哪个取决于您想要的用户体验。

在api中没有明显的方法将次屏幕居中于主屏幕。它只会始终居中于监视器,无论主屏幕在哪里。

这个问题中的一部分是舞台的中心位置的重复。重复的答案中有执行子窗口居中的示例代码。
没错,在公共API中没有关于将子窗口相对于父窗口进行定位的内容。我已经提出了一个功能请求添加帮助方法以将弹出窗口相对于节点进行定位,但到JavaFX 2.2时该功能尚未实现。
我创建了一个样本项目来执行子对话框的相对定位,可能会很有用。
仅为了在父级中居中,您最好在显示子项之前查询舞台位置和宽度,然后在显示时适当设置子项的x和y坐标。所有这些都可以基于窗口的xywidth属性完成。
还有一个JavaFX UI控件沙盒中的对话框项目,可能提供您需要的一些功能,以便您不必自己编写代码。
随着时间的推移,您请求的所有功能可能最终都会出现在JavaFX核心平台中,但我认为JavaFX 2.2还没有完全实现。

再次感谢jewelsea!到目前为止,您已经回答了我几个关于jfx的问题。:) 我只有几个关于这个问题的问题。打开二级舞台的按钮可以被点击多次。一旦打开了二级窗口,我不希望主窗口有任何交互(必须关闭二级窗口才能再次进行交互)。有没有办法做到这一点?此外,在api中没有明显的方法可以将二级屏幕居中在主屏幕上。它总是居中于监视器,无论主屏幕在哪里。 - Matt
1
我更新了答案以回答额外的问题(下次最好在新问题中询问额外的问题 - 这样别人可以更容易地找到他们需要的精确答案)。 - jewelsea
在我进行研究时,我忽略了 Modal。谢谢!我会遵循你的建议,现在会分别发布问题。 - Matt
1
参见:舞台的中心位置,以在父窗口内居中显示子窗口。 - jewelsea

3

我同意jewelsea的观点,但如果您需要同时使用JDialog和JavaFX stages(就像我的情况一样),那么您不能设置主舞台的父级或模态。

我找到的唯一解决方案是使用一个小“hack”:

我使用JNA(Java Native Access API)来编写自己的setAlwaysOnTop()方法,使用User32.INSTANCE.setWindowPos(...)并带有HWND_TOPMOST参数。

编辑: 请参阅微软文档JNA文档


你能分享一下你的实现吗? - Magcus

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