0

I am trying to write an application with java/swing that is able to alternate the transparency of a JWindow or JFrame. For example: There is a JLabel displayed in a JWindow. If a user double clicks the window, it disappears and only the JLabel is displayed. If he double clicks it again, the window should appear again.

Currently, whenever the window disappears, the old background of the image stays at the same place. When i change the size of the window afterwards, the new part is invisible (as the whole JWindow should be). It looks like the full transparent painting of the new background is painted over the old one, so the old one stays visible. You can see it in pic1 and pic2. The gray box is the used JWindow. The red border in pic2 shows the current size of the JWindow with the old visible background and the new invisible part.

I ended up with the following code (manipulated from 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());

    }

}
}

Hope someone knows a workaround!

Community
  • 1
  • 1
  • `I ended up with the following code` - the code doesn't compile, that might be the problem. Post a proper [SSCCE](http://sscce.org/) that demonstrates the problem. – camickr May 27 '15 at 17:17
  • My bad, messed up a few things. The code should compile now. You can see the issue after a double click on the popped up window. – Independent9100 May 27 '15 at 17:53

1 Answers1

0

Currently, whenever the window disappears, the old background of the image stays at the same place

You are adding a second component to the CENTER of the BorderLayout. This does not replace the first component, so both components are painted.

Instead of replacing components the easier solution is to replace the Icon, by using label.setIcon(...)

Or if you must replace components then you need to remove the previous component from the panel before adding the new component.

See: Why does the first panel added to a frame disappear? for more information on what happens when you add multiple components to the CENTER of a BorderLayout.

Community
  • 1
  • 1
camickr
  • 321,443
  • 19
  • 166
  • 288