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

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

在JPanel上添加时的结果:

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

当我使用这一行时会发生这种情况:

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

但是,当我在JFrame上添加相同的.GIF时,黑色方块就不再存在了。 喜欢这个:

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

添加JFrame时的结果:

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

部分类代码:

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

有人可以解释为什么会这样吗? 感谢您的时间和阅读。

编辑:

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

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

你的问题在这里……

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

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

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

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

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

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

布局管理器,布局管理器,布局管理器……

我不能强调布局管理者的重要性。 你依赖的是“魔术”数字,这些数字可能并不总能满足现实……

看看你的代码,我没有看错。 可以肯定的是,我按原样测试了你的代码,添加了我自己的JFrame和JPanel。 这是我最终得到的:

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

当我运行它时,它可以正常工作,没有任何问题。 .GIF是动画的,并在框架中的适当位置。 你可以复制上面的代码,并以同样的方式测试它是否适合你? 另外,您能否向我们展示您初始化包含图像的JFrame和JPanel的代码? 谢谢。

根据您的第一个快照加载图像需要时间。

请查看使用ImageObserver监控以检查图像的状态。

完全加载后,在JPanel添加图像。


示例代码:

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