【问题标题】:Swing: Changing transparency of a JWindow dynamicallySwing:动态更改 JWindow 的透明度
【发布时间】:2015-05-27 17:06:36
【问题描述】:

我正在尝试使用能够交替 JWindow 或 JFrame 的透明度的 java/swing 编写应用程序。例如:有一个 JLabel 显示在一个 JWindow 中。如果用户双击该窗口,它就会消失并且只显示 JLabel。如果他再次双击它,窗口应该会再次出现。

目前,每当窗口消失时,图像的旧背景都会停留在同一位置。当我之后更改窗口的大小时,新部分是不可见的(因为整个 JWindow 应该是)。看起来新背景的全透明绘画覆盖在旧背景上,因此旧背景保持可见。您可以在pic1 pic2 中看到它。灰色框是使用的 JWindow。 pic2 中的红色边框显示了 JWindow 的当前大小,带有旧的可见背景和新的不可见部分。

我最终得到了以下代码(从here 操作)

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;


public class TranscluentWindow
{
public float opacity = 1f;
JFrame frame;

public static void main(String[] args)
{
    new TranscluentWindow();
}

public TranscluentWindow()
{
    EventQueue.invokeLater (new Runnable ()
    {
        @Override
        public void run ()
        {
            try
            {
                UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
            } catch (Exception ex)
            {
            }

            frame = new JFrame ();
            frame.setUndecorated (true);
            frame.setAlwaysOnTop (true);
            frame.addMouseListener (new MouseAdapter ()
            {
                @Override
                public void mouseClicked (MouseEvent e)
                {
                    if(e.getClickCount () % 2 == 0)
                    {
                        if(opacity == 1)
                        {
                            opacity = 0;
                            frame.setSize (200,200);
                            JLabel label =new JLabel ("FOOOOO BAAAR2");
                            label.setForeground (Color.red);
                            frame.add (label);
                            frame.invalidate ();
                            frame.repaint ();
                        }
                        else
                            opacity = 1;
                        frame.invalidate ();
                        frame.repaint ();
                        frame.getContentPane ().invalidate ();
                        frame.getContentPane ().repaint ();
                    }
                }
            });
            frame.setBackground (new Color (0, 0, 0, 0));
            frame.setContentPane (new TranslucentPane ());
            frame.add (new JLabel ("FOO BAR"));
            frame.pack ();
            frame.setLocationRelativeTo (null);
            frame.setVisible (true);
        }
    });
}

class TranslucentPane extends JPanel {

    public TranslucentPane() {
        setOpaque (false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setComposite(AlphaComposite.SrcOver.derive(opacity));
        g2d.setColor(getBackground());
        g2d.fillRect(0, 0, getWidth(), getHeight());

    }

}
}

希望有人知道解决方法!

【问题讨论】:

  • I ended up with the following code - 代码无法编译,这可能是问题所在。发布一个正确的SSCCE 来说明问题。
  • 我的错,搞砸了一些事情。代码现在应该可以编译了。双击弹出的窗口即可看到问题。

标签: java swing transparency


【解决方案1】:

目前,每当窗口消失时,图像的旧背景都会留在原处

您正在向 BorderLayout 的 CENTER 添加第二个组件。这不会替换第一个组件,因此两个组件都被绘制。

更简单的解决方案是使用label.setIcon(...)替换图标,而不是替换组件

或者如果您必须更换组件,那么您需要在添加新组件之前从面板中删除之前的组件。

请参阅:Why does the first panel added to a frame disappear?,了解有关将多个组件添加到 BorderLayout 的 CENTER 时会发生什么的更多信息。

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 2011-03-05
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 2011-10-15
    • 1970-01-01
    相关资源
    最近更新 更多