简体   繁体   English

Win10/11 上的 Java/Swing 应用程序不响应 TaskBar Close-All-Windows GUI 命令

[英]Java/Swing app on Win10/11 not responding to TaskBar Close-All-Windows GUI command

This is an educational app for Win10/11.这是 Win10/11 的教育应用。 It hosts 2 app windows at all times the app is running (even if minimized).它在应用程序运行的任何时候都托管 2 个应用程序 windows(即使已最小化)。

The app auto-saves the user's work (into XML files) during the app-Quit sequence.该应用程序在应用程序退出序列期间自动保存用户的工作(到 XML 文件中)。 To Quit, the user hits the Close button on either window.要退出,用户点击 window 上的关闭按钮。 That triggers the auto-save.这会触发自动保存。

But, the Win OS provides a GUI command down in the Task Bar, a right-click menu tied to the app icon -- Close All Windows.但是,Win OS 在任务栏中提供了一个 GUI 命令,一个与应用程序图标相关联的右键菜单——关闭所有 Windows。

How does Windows signal to the app that the User wants to close all of the app's windows? Windows 如何向应用发出用户想要关闭应用的所有 windows 的信号? It seems that it doesn't bother, and just kills the app.似乎它不打扰,只是杀死了应用程序。

Are there hooks in Java/Swing to pick off this form of user-Quit from the TaskBar? Java/Swing 中是否有钩子可以从任务栏中选择这种形式的用户退出?

Closely related, there are 3 other Win OS actions that indirectly kill an app...Shut Down / Restart / Log Off User.密切相关的是,还有 3 个其他 Win OS 操作会间接杀死应用程序...关闭/重新启动/注销用户。 Same question, does Java have an "OS listener" that can pick off the impending forced Quit?同样的问题,Java 是否有一个“操作系统侦听器”可以挑选即将发生的强制退出?

The Runtime.getRuntime().addShutdownHook(new Thread() } method solves the OS-linkage for Windows Task Bar "Close All Windows". In your app's launch sequence, you want to wait until everything has launched successfully, then call something like this method as the last step in the launch sequence: Runtime.getRuntime().addShutdownHook(new Thread() } 方法解决了 Windows 任务栏“关闭所有窗口”的操作系统链接问题。在您的应用程序的启动序列中,您希望等到一切都成功启动,然后调用类似此方法作为启动序列的最后一步:

''' '''

private static void enableShutdownHookToSaveUserPrefsAndWork() {
    //this code implants the task of recording Prefs & User Work files during the shutdown sequence.
    //Covers the cases where the OS shuts down this app: 
    // tested: 1) Win "Close All Windows", 2) MacOS menu-Quit, 3) MacOS dock-icon Quit
    Runtime.getRuntime().addShutdownHook(new Thread() {

        @Override
        public void run() {
            
            inShutdownSequence = true;
            commenceQuitSequence(); // saves user work; disposes 
            
        }
    });
}
// When this thread suspends, the DestroyJavaVM thread relinquishes all app memory, quits and hands back control to the OS.

''' '''

How did I stumble into this problem?我是怎么偶然发现这个问题的?

I had long ago implemented the ShutdownHook, and it worked fine on the MacOS, the test being if the User's most recent work is saved at Quit-time, using the Dock-icon's "Quit" feature.我很久以前就实现了 ShutdownHook,它在 MacOS 上运行良好,测试是用户最近的工作是否在退出时保存,使用 Dock 图标的“退出”功能。

On Windows10, it was a different story when using the TaskBar "Close All Windows" option....that snuffed the app without saving the user's work (even though the work is saved by the User closing either app window).在 Windows10 上,当使用任务栏“关闭所有 Windows”选项时,情况就不同了……它在不保存用户工作的情况下扼杀了应用程序(即使工作是由用户关闭任一应用程序窗口保存的)。

I finally figure this out.我终于弄清楚了。 As one of those "default" decisions made going into Beta release, it was assumed that the Windows app should have a Java Console (text output) window to help with bug reporting.作为进入 Beta 版的“默认”决定之一,假设 Windows 应用程序应该有一个 Java 控制台(文本输出)window 以帮助报告错误。 The plan was to quash the Console window for V1.0 release.计划是取消 V1.0 版本的控制台 window。

There is no way to wire up the Console window to have its close button tell the app to Quit...closing the Console blindly halts the JVM.无法连接控制台 window 以使其关闭按钮告诉应用程序退出...盲目关闭控制台会停止 JVM。

It also turns out that the TaskBar-icon "Close All Windows" feature closes the Console window first.事实证明,任务栏图标“关闭所有窗口”功能首先关闭了控制台 window。 Whoops!哎呀!

Now that I've modified the Win launcher to launch the JVM with "javaw.exe" instead of "java.exe", there is no console window, and the TaskBar-icon "Close All Windows" command passes control to the JVM --> myApp windows to close themselves, and the User's work is auto-saved.现在我已经修改了 Win 启动器以使用“javaw.exe”而不是“java.exe”来启动 JVM,没有控制台 window,并且任务栏图标“关闭所有窗口”命令将控制权传递给 Z18B5A2317CEDB0E3966 -> myApp windows 关闭自己,并自动保存用户的工作。 This solves the OP.这解决了OP。

The more "forceful" OS-triggered halts of the app (User Log Off, Restart, Shutdown, Task Manager kill-process) seem to call the Java ShutdownHook, but then preempt it during the file writes...resulting in an empty file being written to disk, Based on my testing.更“有力”的操作系统触发的应用程序停止(用户注销、重新启动、关机、任务管理器终止进程)似乎调用 Java ShutdownHook,但随后在文件写入期间抢占它......导致一个空文件根据我的测试,正在写入磁盘。 these processes do WORSE than just killing the JVM.这些进程比仅仅杀死 JVM 更糟糕。 They corrupt the file write in progress.他们破坏了正在进行的文件写入。 BEWARE谨防

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM