在 JPanel 上添加 .GIF 时显示黑色方块

2022-01-24 00:00:00 java swing jpanel imageicon jframe

我的问题是,在将 .GIF 添加到 JPanel 时,它会为 .GIF 显示黑色方形背景.

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

在 JPanel 上添加时的结果:

当我使用这条线时会发生这种情况:

It happens when I use this line:

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

但是,当我在 JFrame 上添加相同的 .GIF 时,黑色方块不再存在.像这样:

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();

在 JFrame 上添加时的结果:

部分类代码:

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.

// 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);

这是第一张图片中显示的 JPanel,没有 JLabel.我不能真正在代码中显示 JFrame 部分,因为它遍布整个班级.但我不认为问题出在 JFrame 所以它可能是这个 JPanel :/

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

推荐答案

你的问题在这里...

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

Swing 不支持基于 alpha 的背景,您的组件要么是透明的,要么不是.

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

这样做意味着组件尝试"使用 alpha 值作为背景填充颜色,但绘制管理器不知道它应该在组件下方绘制,从而导致各种问题和问题

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

现在,这有点棘手.您需要使用 setOpaque(false) 使容器透明,但这意味着背景未绘制.

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.

你需要做的是创建一个自定义组件,将它的 opaque 属性设置为 false 并覆盖它的 paintComponent 方法并填充背景使用基于 alpha 的颜色.我通常喜欢使用 AlphaComposite,但这也很好用...

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

相关文章