Set JDialog background to transparent with NimbusLookAndFeel

350 views Asked by At

I am writing a desktop app with Swing. My UI's LookAndFeel is set to NimbusLookAndFeel using:

for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }

I am trying to set the background of a JDialog to transparent so that some animations drawn on a JPanel will show over the transparent JDialog.

To achieve this, I have used:

 JDialog dialog = new JDialog(frame, "Loading...", false);


        dialog.getRootPane().setOpaque(false);
       dialog.getContentPane().setBackground(new Color(0, 0, 0, 0));
        dialog.setBackground(new Color(0, 0, 0, 0));

I have also set the child JPanel's opaque property to false.

Unfortunately, a background which I have traced to the JDialog keeps appearing only when the NimbusLookAndFeel is used.

If I do not use NimbusLookAndFeel, it works, as the JDialog's background disaappears.

Here is code that reproduces this problem:

    package com.examples.me;


    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.WindowConstants;



public class Example extends JPanel {

    JDialog dialog;

    public Example(JFrame frame, boolean withNimbus) {

        if (withNimbus) {
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());

                        break;
                    }
                }
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(Example.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }

        }

        setOpaque(false);

        setSize(420, 350);

        dialog = new JDialog(frame, "Loading...", false);

        dialog.add(Example.this);
        dialog.setAlwaysOnTop(true);
        dialog.setResizable(false);
        dialog.setUndecorated(true);

        dialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

        dialog.setSize(getSize());
        dialog.setLocationRelativeTo(null);

        dialog.getRootPane().setOpaque(false);
        dialog.getContentPane().setBackground(new Color(0, 0, 0, 0));
        dialog.setBackground(new Color(0, 0, 0, 0));

    }

    @Override
    protected void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        int w = getWidth();
        int h = getHeight();

        Graphics2D g = (Graphics2D) gg;

        g.setStroke(new BasicStroke(2));
        g.setColor(Color.red);
        g.drawRoundRect(1, 1, w - 2, h - 2, 64, 64);

        g.drawLine(1, h / 2, w - 2, h / 2);

        g.drawLine(w / 2, 1, w / 2, h - 2);

    }

    @Override
    public boolean isVisible() {
        if (dialog != null) {
            return super.isVisible() && dialog.isVisible();
        }

        return super.isVisible();

    }

    @Override
    public void setVisible(boolean aFlag) {
        super.setVisible(aFlag); //To change body of generated methods, choose Tools | Templates.
        if (dialog != null) {
            dialog.setVisible(aFlag);
        }

    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                JFrame frame = new JFrame("Nimbus Failure Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(700, 450);

                Example p = new Example(frame , true);

                // p.setSize(500, 400);
                // f.add(p);
                frame.setLocationRelativeTo(null);

                p.setVisible(true);

                frame.setVisible(true);

            }
        });

    }

}

To see that it works normally without NimbusLookAndFeel, set the withNimbus parameter to false in the constructor. That is the expected behaviour.

How do I make a JDialog transparent when I am using a Nimbus look-and-feel?

Thanks.

0

There are 0 answers