4

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 :/

  • Its working perfectly for me as per your code. Can you try this code that you have shared without any background images. – Braj Apr 07 '14 at 23:12
  • Looks good for me too with similar code: [GifTest](http://luniks.net/other/GifTest.png) – Torsten Römer Apr 07 '14 at 23:27
  • Could you guys please try with the EDIT code I posted in the original post? Thanks! – user3508709 Apr 07 '14 at 23:34
  • Oops... [GifTest2](http://luniks.net/other/GifTest2.png) – Torsten Römer Apr 07 '14 at 23:41
  • I get exactly the same as that with or without background if the gif is added on that JPanel. – user3508709 Apr 07 '14 at 23:45
  • 1
    When you comment p2.setBackground(new Color(0,0,0,150)); it is fine again so the issue must be there somewhere... – Torsten Römer Apr 07 '14 at 23:46
  • 2
    `p2.setLayout(null)` that's one of your problems – nachokk Apr 07 '14 at 23:46
  • We are misusing stackoverflow as a chat tool :-/ – Torsten Römer Apr 07 '14 at 23:48
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). 2) Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Apr 08 '14 at 02:15

2 Answers2

3

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

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();
Braj
  • 46,415
  • 5
  • 60
  • 76
  • It didn't work unfortunately. It's still the same as before but please check if you are getting the same problem like me when you use the JPanel code I posted in the original post. Thank you. – user3508709 Apr 07 '14 at 23:44
  • Now its clear from your new code as @MadProgrammer has already answered. – Braj Apr 08 '14 at 06:54