Question

My problem is that when adding a .GIF to a JPanel, it shows this black square background for the .GIF.

Result when adding on JPanel:

http://i.imgur.com/W1HXgZ1.jpg

It happens when I use this line:

p2.add(loadBar); // where p2 = new JPanel();

However, when I add the same .GIF on the JFrame, the black square is not there anymore. Like this:

jf.add(loadBar); // where jf = new JFrame();

Result when adding on JFrame:

http://i.imgur.com/0pMAS30.jpg

Part of the class code:

String loadLink = "http://i.imgur.com/mHm6LYH.gif";
        URL ajaxLoad = null;
        try {
            ajaxLoad = new URL(loadLink);
        } catch (MalformedURLException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }
        ImageIcon loading = new ImageIcon(ajaxLoad);
        JLabel loadBar = new JLabel(loading);
        loadBar.setBounds(70, 60, 54, 55);
        loadBar.setOpaque(false);
        //jf.add(loadBar);
        p2.add(loadBar);

Could someone please explain why it is happening like this? Thank you for your time and reading.

EDIT:

// Creates the Initialization Panel
        p2 = new JPanel();
        // Sets the background, black with 125 as alpha value
        // This is less transparent
        p2.setLayout(null);
        p2.setBackground(new Color(0,0,0,150));
        // Sets a border to the JPanel
        p2.setBorder(new LineBorder(Color.WHITE));
        // Sets some size to the panels
        p2.setBounds(20, 20, 200, 150);

        // Adds the loading gif
        String loadLink = "http://i.imgur.com/mHm6LYH.gif";
        URL ajaxLoad = null;
        try {
            ajaxLoad = new URL(loadLink);
        } catch (MalformedURLException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }
        ImageIcon loading = new ImageIcon(ajaxLoad);
        JLabel loadBar = new JLabel(loading);
        loadBar.setBounds(70, 60, 54, 55);
        loadBar.setOpaque(false);
        p2.add(loadBar);

That is the JPanel which is shown in the first image without the JLabel. I can't really show the JFrame part in the code because it is spread all over the class. But I don't think the problem is with JFrame so it could be this JPanel :/

Was it helpful?

Solution

Your problem is here...

p2.setBackground(new Color(0,0,0,150));

Swing does not support alpha based backgounds, either your component is transparent or it's not.

Doing this means that the component "attempts" to use the alpha value as the background fill color, but the paint manager doesn't know it should paint beneath the component, causing all sorts of problems and issues

Now, this a little tricky. You need to make the container transparent by using setOpaque(false), but this now means that the background is not painted.

What you need to do is create a custom component, set it's opaque property to false and override it's paintComponent method and fill the background with your alpha based color. I normally like using a AlphaComposite, but this works as wel...

Spinny

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class TranslucentPanelExample {

    public static void main(String[] args) {
        new TranslucentPanelExample();
    }

    public TranslucentPanelExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                try {
                    JLabel background = new JLabel(
                            new ImageIcon(ImageIO.read(
                                            getClass().getResource("/background.jpg"))));
                    background.setLayout(new GridBagLayout());
                    background.add(new WaitPane());

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(background);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
        });
    }

    public class WaitPane extends JPanel {

        public WaitPane() {
            setLayout(new GridBagLayout());
            setBorder(new EmptyBorder(12, 12, 12, 12));
            // This is very important
            setOpaque(false);
            setBackground(new Color(0, 0, 0, 150));

            String loadLink = "http://i.imgur.com/mHm6LYH.gif";
            URL ajaxLoad = null;
            try {
                ajaxLoad = new URL(loadLink);
            } catch (MalformedURLException e3) {
                // TODO Auto-generated catch block
                e3.printStackTrace();
            }

            ImageIcon loading = new ImageIcon(ajaxLoad);
            JLabel loadBar = new JLabel(loading);
            loadBar.setHorizontalAlignment(JLabel.CENTER);
            loadBar.setVerticalAlignment(JLabel.CENTER);
            add(loadBar);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
        }

    }

}

Layout managers, layout managers, layout managers...

I can't stress enough how important layout managers are. You are relying on "magic" numbers which may not always meet reality...

OTHER TIPS

It's taking time to load the image as per your first snapshot.

Please have a look at Monitoring with an ImageObserver to check the status of the image.

Add the image in JPanel when its fully loaded.


Sample code:

    new Thread(new Runnable() {

        @Override
        public void run() {
            int width = loading.getIconWidth();

            if (width >= 0) {
                isImageLoaded = true;
                p2.add(loadBar);
                return;
            }

            // Wait if the image is not loaded yet
            while (!isImageLoaded) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    }).start();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top