Hi,

I’m having troubles figuring to which extent full translucency (down to the desktop background) is supported by Swing. Behaviors are not the same depending on the component used (light or heavy), the JDK, as well as the graphics card. For instance, why the following simple example requires a JDK > 8?

Using a newer JDK, things mostly work fine (on Linux). I’ve got flickering issues, but my main problem is that setting the "sun.java2d.opengl" breaks everything. It seems like the underlying FBO created don’t have any alpha channel at all. The final texture used by the desktop compositor is not alpha-premultiplied and have a global 0.0 or 1.0 alpha value (I’ve seen both cases). However, I didn’t found any known issue describing this basic problem. Am I missing something obvious in my code here?

- Florent




// Start of code

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsDevice.WindowTranslucency;
import java.awt.Rectangle;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;

public class SimpleTranslucentFrame {

    @SuppressWarnings("serial")
    public static void main(String[] args) {

        String openglPropertyName = "sun.java2d.opengl";
        JLabel openglLabel = new JLabel(openglPropertyName + "=" + System.getProperty(openglPropertyName, "false"));

        JLabel swingLabel = new JLabel("Swing");
        swingLabel.setFont(swingLabel.getFont().deriveFont(48f));
        new Timer(500, e -> swingLabel.setText(new StringBuilder(swingLabel.getText()).reverse().toString())).start();

        JButton closeButton = new JButton("Fermer");
        closeButton.addActionListener(event -> System.exit(0));

        JPanel panel = new JPanel(new BorderLayout(10, 10));
        panel.setBorder(new EmptyBorder(10, 10, 10, 10));
        panel.setOpaque(false);
        panel.add(openglLabel, BorderLayout.NORTH);
        panel.add(swingLabel);
        panel.add(closeButton, BorderLayout.SOUTH);

        // Required custom content pane (a JDK > 8 is also required).
        JPanel contentPane = new JPanel(new BorderLayout()) {
            @Override
            public void paint(Graphics g) {
                ((Graphics2D) g).setBackground(getBackground());
                Rectangle clipBounds = g.getClipBounds();
                g.clearRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
                super.paint(g);
            }
        };
        contentPane.setBackground(new Color(0, 0, 0, 0));
        contentPane.setOpaque(false);

        JFrame frame = new JFrame();
        GraphicsDevice device=frame.getGraphicsConfiguration().getDevice();
        // Fun fact: PERPIXEL_TRANSLUCENT =/=> TRANSLUCENT (with a Nvidia Quadro 4000)         assert device.isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSLUCENT);
        frame.setUndecorated(true);
        frame.setBackground(new Color(0, 0, 0, 0));
        frame.setContentPane(contentPane);
        frame.add(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

// End of code

Reply via email to