标签中 gif 的 Java 问题

Posted

技术标签:

【中文标题】标签中 gif 的 Java 问题【英文标题】:Java problems with gif in label 【发布时间】:2018-09-24 09:11:48 【问题描述】:

我尝试放入 JPanel 的 gif 在单击触发它的按钮后没有显示,直到我调整窗口大小。当它出现时,它不适合 JPanel 并且没有动画。我查看了几篇处理此问题的帖子,但我不明白如何在我的情况下使用它们。

/*
 * Author: Raymo111
 * Date: 13/04/2018
 * Description: Wishes happy birthday to a special someone
 */

//Imports java GUI classes
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

// Main class with JFrame and ActionListener enabled
public class Happy_Birthday_GUI extends JFrame implements ActionListener 

    // Class variables
    private static JButton startButton = new JButton("CLICK TO START");
    private static JPanel startPanel = new JPanel(), gifPanel = new JPanel();
    private static Color blue = new Color(126, 192, 238), pink = new Color(255, 192, 203);
    private static GridLayout grid1 = new GridLayout(1, 1);

    // Constructor
    public Happy_Birthday_GUI() 

        // Initial screen
        startButton.addActionListener(this);
        startButton.setFont(new Font("Comic Sans MS", Font.PLAIN, 50));
        startPanel.setLayout(grid1);
        startPanel.add(startButton);
        startPanel.setBorder(BorderFactory.createLineBorder(blue, 100));
        startButton.setBackground(pink);
        getContentPane().add(startPanel);

        // Sets title, size, layout (grid 1x1), and location of GUI window (center)
        setTitle("Happy Birthday from Dolphin");
        setSize(840, 840);
        setLayout(grid1);
        setLocationRelativeTo(null);
        setVisible(true);

    

    // Main method
    public static void main(String[] args) 
        new Happy_Birthday_GUI();
    

    // Action Performed method
    public void actionPerformed(ActionEvent event) 

        // Proceed to gif and song
        if (startButton == event.getSource()) 
            getContentPane().removeAll();
            BufferedImage dolphin;
            gifPanel.setLayout(grid1);
            gifPanel.setBorder(BorderFactory.createLineBorder(pink, 100));
            try 
                dolphin = ImageIO.read(new File("C:\\Users\\raymo\\Pictures\\dolphin.gif"));
                JLabel gifLabel = new JLabel(new ImageIcon(dolphin));
                gifPanel.add(gifLabel);
             catch (IOException e) 
                e.printStackTrace();
            
            getContentPane().add(gifPanel);
        
    



这是 dolphin.gif。很可爱。


如何让它在单击开始按钮后立即显示为适合 JPanel 的动画 gif?提前致谢。

【问题讨论】:

不要使用ImageIO.read 阅读动画 Gif,它不起作用。相反,您需要使用ImageIcon @MadProgrammer 我该如何使用它? ...您可以先阅读JavaDocs 或查看tutorials @MadProgrammer 嗯...好吧,但我如何让它立即刷新并让它填满面板? @MadProgrammer 谢谢! gif工作。现在调整大小并立即显示? 【参考方案1】:

BufferedImage 不支持绘制动画 Gif,您需要使用 Image(或者最好是 ImageIcon)。

这可以直接应用于JLabel,它会自行执行动画操作。

适合他 JPanel 的动画 gif?

好的,这是一个复杂得多的问题。一种方法是将 Gif 转换为所需的大小,但不用说,这非常非常复杂。

更简单的解决方案可能是使用AffineTransform 并缩放图像以满足组件本身的要求。这需要一个自定义组件,能够计算比例并绘制图像的每一帧。

幸运的是,JPanelImageObserver,这意味着它能够绘制 gif 动画

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test 

    public static void main(String[] args) 
        new Test();
    

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            
        );
    

    public class TestPane extends JPanel 

        private ImageIcon image;

        public TestPane() 
            image = new ImageIcon("/Users/swhitehead/Downloads/NbENe.gif");
        

        @Override
        public Dimension getPreferredSize() 
            return new Dimension(600, 600);
        

        @Override
        protected void paintComponent(Graphics g) 
            int imageWidth = image.getIconWidth();
            int imageHeight = image.getIconHeight();

            if (imageWidth == 0 || imageHeight == 0) 
                return;
            
            double widthScale = (double)getWidth() / (double)imageWidth;
            double heightScale = (double)getHeight() / (double)imageHeight;
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(image.getImage(), AffineTransform.getScaleInstance(widthScale, heightScale), this);
            g2d.dispose();
        

    


【讨论】:

这行得通!谢谢你,谢谢你,谢谢你!也能有效利用资源!【参考方案2】:

我试图放入一个JPanel,点击按钮后没有显示

当您从可见的 GUI 添加(或删除)组件时,基本代码是:

panel.add(...);
panel.revalidate();
panel.repaint();

revalidate() 需要调用布局管理器,以便为组件指定大小。

没有动画。

使用带有 ImageIcon 的 JLabel 来显示图像。 JLabel 将为 gif 设置动画。

当它出现时,它不适合 JPanel 并且

您可以尝试Stretch Icon,它旨在填充标签可用的空间。

【讨论】:

重绘不起作用,如何使用拉伸图标的东西? Repainting is not working. – - 好吧,为什么要将标签添加到面板,然后将面板添加到内容窗格?在这种情况下,您需要 revalidate() 内容窗格,因为这是您实际添加到框架的组件。在这种情况下,您只需在 JFrame 上使用 revalidate()。 使用revalidate();repaint(); 会出现空白屏幕。 gives a blank screen. - 一旦使用 ImageIcon(...) 而不是 ImageIO 加载图像,我在这里建议的一切对我来说都很好。您错误地更改了代码。 The stretchIcon thing I don't know how to use, - 就像 ImageIcon。阅读链接。下载课程。查看 API 并选择适当的构造函数来读取图像。 @Raymo111,你是什么意思?你是一个无视我建议的人。我建议使用 StretchIcon,它与 ImageIcon 一样易于使用。 StretchIcon 也可以用于任何其他可以使用图标(如 JButton)的组件(尽管动画 gif 仅适用于 JLabel)。我还告诉过您,您的代码很好,您只需在正确的位置添加 revalidate() 即可。如果事实我重复了多次。那是什么意思?在这次谈话中,你没有一次对帮助说“谢谢”。您所做的就是不断寻求更多帮助!【参考方案3】:

我最终做了:

gifPanel.add(new TestPane());
getContentPane().add(gifPanel);
revalidate();
repaint();

使用 camickr 的 revalidate 和 repaint,以及 MadProgrammer 的 TestPane 类, 这非常适合让 gif 动画、正确调整大小并立即显示。

【讨论】:

以上是关于标签中 gif 的 Java 问题的主要内容,如果未能解决你的问题,请参考以下文章

在标签栏中添加图像 (.gif)

LWUIT:将 GIF 图像添加到标签

如何用html标签来显示gif图片

解决微信小程序通过img标签加载GIF只能播放一次问题

javascript 正则替换IMG标签

如果我更改标签并返回,我的 GIF 会冻结一段时间(p5.js)