经过对 Windows 动画的进一步研究,看起来可以组合出一个解决方案。这似乎更多是操作系统问题,而不仅仅是 JavaFX。
通过在 start() 中修改它,我能够使初始窗口在最小化和动画时保持未装饰状态:
int newStyle = oldStyle | 0x00020000 | 0x00C00000;
但是,最小化并重新打开后,Windows 边框显得很奇怪。
然后,我尝试在图标化时使用 ChangeListener 来交换 Windows 样式。
stage.iconifiedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if (t1.booleanValue() == true) {
int newStyle = oldStyle | 0x00020000 | 0x00C00000;
user32.SetWindowLong(hwnd, GWL_STYLE, newStyle);
} else if (t1.booleanValue() == false) {
int newStyle = oldStyle | 0x00020000;
user32.SetWindowLong(hwnd, GWL_STYLE, newStyle);
}
}
});
这成功地使窗口非最小化动画能够一致地正常工作,同时使(可见)舞台无边框。
一旦找到重新应用的最佳方法,我就可以使最小化动画正常工作:
int newStyle = oldStyle | 0x00020000 | 0x00C00000;
user32.SetWindowLong(hwnd, GWL_STYLE, newStyle);
就在舞台被图标化之前,并且边框对用户不可见。实施后,其工作方式可能与下面第一个链接中的 C# 解决方案类似。基本上,上面的 ChangeListener 的作用正好相反。
我认为我们需要另一个线程在后台监听来完成这个解决方案,等待图标化事件发生。我认为 stage.isIconified() == false 应该是事件触发时的情况,然后我们在后台线程中执行必要的任务来设置上述代码。然后,(...有点工作)changeListener 会将其重置回没有动画的非框架窗口,当取消最小化时,直到再次最小化。
有一个小错误,第一个未最小化显示的舞台底部部分被剪切和复制了一点,但在后续操作后它消失了。我们可能需要尝试将第二个十六进制更改为触发动画的其他内容,并在 ChangeListener 之外和另一个线程中设置所有内容。
我计划很快在我自己的外汇程序中完成这个工作。我还是一名学生,所以我对多线程和服务不太有经验,但我对如何去做有一个好主意,这只需要几个小时的黑客攻击。
如果您在此期间取得任何进展,请告诉我!这是一个很好的起点。目前还没有人在 Java 中解决这个问题。我正在阅读一些关于像 Steam 这样的无边界程序已经做到了这一点的讨论,但我认为没有人能够完全弄清楚他们是如何实现这一目标的,我怀疑这是通过下面的 C# hack 实现的。但是,这对于我们的目的来说已经足够了。
与解决无边框/未装饰动画有关的链接:
https://stackoverflow.com/a/31489766/7234125 https://stackoverflow.com/a/31489766/7234125
^ 我们需要实现这个答案,选项 #1,从 C# 到 Java
使用 Areo Snap、阴影、最小化动画和抖动的无边框窗口 https://stackoverflow.com/questions/16765561/borderless-window-using-areo-snap-shadow-minimize-animation-and-shake
http://pinvoke.net/default.aspx/Constants/Window%20styles.html http://pinvoke.net/default.aspx/Constants/Window%20styles.html