JavaFX通过动画最小化和最大化未修饰的舞台

时间:2018-06-24 09:09:43

标签: javafx jna

我在以下问题中使用了可接受的答案:JavaFX Minimizing Undecorated Stage,以使我的应用正确最小化。

但是,不幸的是,默认的Windows最小化和最大化动画根本没有显示(窗口只是显示和消失)。

我知道有可能使动画显示在未修饰的窗口中,因为我有一个具有这种行为的应用程序(PotPlayer)。

如何使动画与JNA一起显示?

编辑:这是一个有效的Kotlin代码段,用于适当地最小化JavaFX窗口,并增加了赏金。

fun makeMinimizable(stage: Stage) {
         val user32 = User32.INSTANCE
         val hWnd = user32.FindWindow(null, stage.title)
         val oldStyle = user32.GetWindowLong(hWnd, WinUser.GWL_STYLE)
         val newStyle = oldStyle or 0x00020000 // WS_MINIMIZEBOX
         user32.SetWindowLong(hWnd, WinUser.GWL_STYLE, newStyle)
    }

1 个答案:

答案 0 :(得分:0)

在对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和其他线程中设置所有内容。

我计划很快在自己的fx程序中完成此操作。我仍然是一名学生,所以我对多线程和服务没有太多的经验,但是我对如何进行处理有一个很好的主意,只需花几个小时就可以破解。

如果您有任何进展,请告诉我!这是一个很好的起点。尚无人用Java解决此问题。我正在阅读有关Steam等无边界程序已完成此操作的一些讨论,但我认为没有人能完全弄清楚他们是如何完成的,我怀疑这是通过下面的C#hack实现的。但是,对于我们的目的而言已经足够了。

与解决无边界/未经修饰的动画有关的链接:

https://stackoverflow.com/a/31489766/7234125

^我们需要实现从C#到Java的答案,选项#1

https://exceptionshub.com/borderless-window-using-areo-snap-shadow-minimize-animation-and-shake.html

http://pinvoke.net/default.aspx/Constants/Window%20styles.html