我已经阅读过使用JDialog来包装JFXPanel以使用JDialog的alwaysOnTop方法。它有效,但我对这个黑客有一个小问题。
由于我正在使用这种技术为我的主应用程序(弹出窗口等)创建辅助窗口,我需要将它们设置在主窗口的顶部。如果我使用包装器hack来执行此操作,则顶部面板“始终位于所有(包括其他应用程序)的顶部”。
有没有办法将辅助屏幕仅放在我的应用程序之上?我不喜欢可以在我的应用程序的主窗口和辅助窗口之间拖动另一个应用程序。
答案 0 :(得分:15)
我建议不要使用JDialog和JFXPanel,而只使用JavaFX Stages。
在显示辅助阶段之前,将辅助屏幕设为Stage
并调用secondaryStage.initOwner(primaryStage)。
从舞台文档:
舞台可以选择拥有所有者窗口。当窗口是舞台的所有者时,它被称为该舞台的父级。 。 。舞台将始终位于其父窗口的顶部。
我相信设置第二阶段的所有者,正确地满足了“仅在我的应用程序之上的辅助屏幕”的要求。
更新:回答评论中的其他问题
一旦辅助开放,我不希望与主舞台有任何互动(必须关闭辅助窗口才能再次进行交互)。
要阻止对主要阶段的输入,在显示第二阶段之前,请致电:secondaryStage.initModality(Modality.WINDOW_MODAL)。
如果您希望阻止对其他任何应用程序窗口的所有输入,则可以使用APPLICATION_MODAL而不是WINDOW_MODAL - 使用哪一个取决于您想要的用户体验。
在api中没有任何明显的东西可以将辅助屏幕置于主屏幕中心。无论主屏幕在哪里,它总是以显示器为中心。
问题的这一部分是Center location of stage的副本。副本的答案包含用于执行子窗口居中的示例代码。
没错,公共api中没有任何内容围绕父窗口定位子窗口。我已经为此功能Add helper methods for positioning popups relative to nodes提交了功能请求,但功能请求尚未从JavaFX 2.2开始实现。
我创建了一个sample project来对子对话框进行相对定位,这可能很有用。
只是为了在父母中心居中,最好在显示孩子之前查询舞台位置和宽度,然后在显示孩子时适当地设置孩子的x和y坐标。所有这些都可以基于Windows的x,y和width属性来完成。
JavaFX UI controls sandbox中还有一个对话框项目可能会提供您需要的一些功能,因此您无需自己编写代码。
随着时间的推移,您所请求的所有功能可能最终都会出现在JavaFX核心平台中,但我认为JavaFX 2.2还没有完全实现。
答案 1 :(得分:3)
我同意jewelsea的意见,但是如果您需要使用JDialog 和 JavaFX阶段(就像我的情况一样),那么您就无法设置您的primaryStage的父级或模态。
我找到的唯一解决方案是使用一点“黑客”:
我使用JNA,Java Native Access API使用带有HWND_TOPMOST参数的setAlwaysOnTop()
来执行我自己的User32.INSTANCE.setWindowPos(...)
方法。
修改:请参阅microsoft doc 和jna doc