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.