我正在尝试用java / swing编写一个能够交替使用JWindow或JFrame的透明度的应用程序。例如:JWindow中显示了一个JLabel。如果用户双击该窗口,它将消失,仅显示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());
}
}
}
希望有人知道解决方法!
答案 0 :(得分:0)
目前,只要窗口消失,图像的旧背景就会停留在同一个地方
您正在向BorderLayout的CENTER添加第二个组件。这不会取代第一个组件,因此两个组件都被绘制。
使用label.setIcon(...)
或者如果您必须更换组件,则需要在添加新组件之前从面板中删除以前的组件。
有关将多个组件添加到BorderLayout的CENTER时会发生什么的更多信息,请参阅:Why does the first panel added to a frame disappear?。