首页 > 解决方案 > 隐藏的 JDialog 在 Windows 10 任务栏预览中仍然可见

问题描述

关闭后JDialog配置为不可见。HIDE_ON_CLOSE但它在 Windows 任务栏的预览预览中仍然可见。只有在主窗口被最小化和再次最大化后,预览才会被纠正。当然,可以处理对话框而不是隐藏它,但这不是我的目标。

代码示例:

    public static void main( String[] args ) throws Exception {
        JFrame frame = new JFrame();
        frame.setTitle( "frame" );
        frame.setSize( 700, 700 );
        frame.setVisible( true );
        frame.setDefaultCloseOperation( JDialog.EXIT_ON_CLOSE );
    
        JDialog d = new JDialog( frame ); // modeless dialog
        d.setTitle( "dialog" );
        d.setSize( 300, 300 );
        d.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );
        d.setVisible( true );
    }

描述问题的 GIF

标签: javawindowsswinguser-interfacejdialog

解决方案


请尝试在隐藏之前直接在对话框上设置 WS_EX_TOOLWINDOW 样式。然后立即将其移除(这样就不会影响后续节目的渲染)。

任务栏上不允许使用工具栏窗口,因此不能预览。这是一个 hack,但它适用于我在 Windows 11 中的类似问题。

这是在 Windows 11 上对我有用的代码。我能够使用 JDK17 在 Windows 11 上重现该错误。

您需要https://github.com/java-native-access/jnajna.jarplatform.jar)。没有它,我找不到设置 win32 窗口样式的方法。

javac -cp .;./jna.jar;./platform.jar jdtest.java

import javax.swing.JFrame;
import javax.swing.JDialog;
import java.awt.event.*;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
public class jdtest
{
    
    public static int WS_EX_TOOLWINDOW = 0x00000080;
    public static void changeStyle(HWND hwnd, boolean hiding) {
        int exStyle = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
        if (hiding) {
            User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, exStyle | WS_EX_TOOLWINDOW);
        } else {
            User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, exStyle & ~WS_EX_TOOLWINDOW);
        }
    }
    
    private static HWND getHWnd(JDialog d) {
        HWND hwnd = new HWND();
        hwnd.setPointer(Native.getWindowPointer(d));
        return hwnd;
    }

    public static void main( String[] args ) throws Exception {
        JFrame frame = new JFrame();
        frame.setTitle( "frame" );
        frame.setSize( 700, 700 );
        frame.setVisible( true );
        frame.setDefaultCloseOperation( JDialog.EXIT_ON_CLOSE );

        JDialog d = new JDialog( frame ); // modeless dialog
        d.setTitle( "dialog" );
        d.setSize( 300, 300 );
        d.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );

        d.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                changeStyle(getHWnd(d), true);
            }
        });
        d.addWindowListener(new WindowAdapter() {
            public void windowOpening(WindowEvent e) {
                changeStyle(getHWnd(d), false);
            }
        });

        d.setVisible( true );
    }
}

推荐阅读