去除图标后,JDialog失去了不透明度

时间:2014-10-22 18:35:42

标签: java swing

创建一个透明且未涂底漆的JDialog,其父级为JFrame 在iconify / deiconify序列中将失去透明度。

示例:

final JFrame f = new JFrame();
f.setSize(200, 200);

final JDialog d = new JDialog(f, false);
d.setSize(200, 200);
d.setUndecorated(true);
d.setOpacity(.8f);

f.setLocationRelativeTo(null);
d.setLocation(f.getLocation().x + 210, f.getLocation().y);

f.setVisible(true);
d.setVisible(true);

在iconify之前,JDialog创建得很好。这是一个截图。

enter image description here

在iconify / deiconify序列之后,JDialog是100%不透明的。

enter image description here

我正在寻找这个问题的解决方案,并且我正在考虑做某事 错误或遗漏了一些代码。

我的环境是Java(TM)SE运行时环境(版本1.8.0_11-b12) 在Microsoft Windows [版本6.1.7601]上运行。

2014-11-13:此问题存在一个开放的JDK错误

JDK-8062946 Transparent JDialog will lose transparency upon iconify/deiconify sequence. 

https://bugs.openjdk.java.net/browse/JDK-8062946

2 个答案:

答案 0 :(得分:2)

对我来说似乎有点像虫子。

以下似乎可以在Windows 7上使用JDK7:

f.addWindowListener( new WindowAdapter()
{
    @Override
    public void windowDeiconified(WindowEvent e)
    {
        d.setVisible(false);
        d.setVisible(true);
    }
});

答案 1 :(得分:1)

尝试以下方法。我对未修饰的JDialog有各种各样的问题,当我找到一个。时 绕过一个新的症状我把它添加到这个方法。这是一个修剪过的例子。添加错误检查,异常处理并根据需要进行修改(例如,如果您的应用创建并销毁传递的 parentWindow 对象,则添加侦听器删除代码)。

package trimmed.stackoverflow.example;

import java.awt.Color;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JDialog;
import javax.swing.SwingUtilities;

public class Helper_Swing {

private static Helper_Swing instance;

private Helper_Swing() {
    instance = this;
}

public static Helper_Swing getInstance() {
    return instance == null ? new Helper_Swing() : instance;
}

private static class J42WindowAdapter extends WindowAdapter {

    final private Window  window;
    final private JDialog dialog;
    private Color         colorBG = null;
    private float         opacity = 0.0f;

    private J42WindowAdapter(final Window window, final JDialog dialog) {
        super();
        this.window = window;
        this.dialog = dialog;
        this.colorBG = window.getBackground();
        this.opacity = window.getOpacity();
    }

    @Override
    public void windowIconified(final WindowEvent e) {
        colorBG = dialog.getBackground();
        opacity = dialog.getOpacity();
        dialog.setOpacity(1.0f);  // Must call 1st
        dialog.setBackground(Color.BLACK); // Must call 2nd
    }

    @Override
    public void windowDeiconified(final WindowEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                dialog.setBackground(colorBG);
                dialog.setOpacity(opacity);
                dialog.setVisible(true);
                dialog.repaint();
            }
        });
    }
}

public void bugFix_transparentJDialog(final Window parentWindow, JDialog childWindow) {
    if (parentWindow != null && childWindow != null && childWindow.isUndecorated()) {
        final WindowListener[] listeners = parentWindow.getWindowListeners();
        for (int x = 0; x != listeners.length; x++) {
            if (listeners[x] instanceof J42WindowAdapter) {
                final J42WindowAdapter adapter = (J42WindowAdapter) listeners[x];
                if (adapter.window == parentWindow && adapter.dialog == childWindow) {
                    childWindow = null;
                    break;
                }
            }
        }
        if (childWindow != null) {
            parentWindow.addWindowListener(new J42WindowAdapter(parentWindow, childWindow));
        }
    }
}

}

用法示例:

Helper_Swing.getInstance().bugFix_transparentJDialog(parentWindow, dialog);