Black square showing when adding a .GIF on JPanel

百般思念 提交于 2019-12-01 06:46:53

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...

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...

Looking at your code, I see nothing wrong. Just to be sure, I tested your code out as is, adding in my own JFrame and JPanel. Here is what I ended up with:

import javax.swing.*;
import java.net.*;

public class Test {
public static void main(String[] args) {
    JFrame frame = new JFrame("Test");
    frame.setSize(600, 400);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    String loadLink = "http://i.imgur.com/mHm6LYH.gif";
    URL ajaxLoad = null;
    try {
        ajaxLoad = new URL(loadLink);
    } catch (MalformedURLException e3) {
        e3.printStackTrace();
    }
    ImageIcon loading = new ImageIcon(ajaxLoad);
    JLabel loadBar = new JLabel(loading);
    loadBar.setBounds(70, 60, 54, 55);
    loadBar.setOpaque(false);
    panel.add(loadBar);    
    frame.add(panel);
    frame.setVisible(true);
    }
}

When I ran it, it worked as it should, without any problems. The .GIF was animated and in its proper place in the frame. Could you copy the code above and test that it works for you the same way? Also, could you show us your code in which you initialize your JFrame and JPanel that contain the image? Thanks.

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();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!