Problèmes Java avec gif dans l'étiquette


Un GIF que j'ai essayé de mettre dans un JPanel n'apparaît pas après avoir cliqué sur le bouton qui le déclenche jusqu'à ce que je redimensionne la fenêtre. Quand il apparaît, il ne correspond pas au JPanel et n'est pas animé. J'ai regardé plusieurs articles qui traitaient de cela mais je ne comprends pas comment les utiliser dans mon cas.

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

}

Voici dolphin.GIF. Elle est mignonne.

Dauphin.GIF


Comment puis-je le faire apparaître immédiatement après avoir cliqué sur le bouton Démarrer en tant que gif animé qui correspond au JPanel? Merci à l'avance.

Author: Raymo111, 2018-04-14

3 answers

J'ai essayé de mettre dans un JPanel n'apparaît pas après avoir cliqué sur le bouton

Lorsque vous ajoutez (ou supprimez) des composants d'une interface graphique visible, le code de base est:

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

Le revalidate() est nécessaire pour appeler le gestionnaire de mise en page afin que le composant reçoive une taille.

N'Est pas animé.

Utilisez un JLabel avec un ImageIcon pour afficher les images. Un JLabel animera le gif.

Quand il apparaît, il ne correspond pas au JPanel et

Vous pouvez essayer l'icône Stretch qui est conçue pour remplir l'espace disponible pour l'étiquette.

 1
Author: camickr, 2018-04-14 00:23:21

BufferedImage ne prend pas en charge la peinture de GIF animés, vous devrez plutôt utiliser Image (ou de préférence, ImageIcon).

Cela pourrait ensuite être appliqué directement à un JLabel, qui effectuera l'opération d'animation elle-même.

Gif animé qui correspond à JPanel?

D'accord, c'est un problème beaucoup plus complexe. Une approche serait de convertir le GIF à la taille requise, mais inutile de dire que c'est très, très complexe.

Une solution plus simple pourrait être de utilisez un AffineTransform et mettez l'image à l'échelle pour répondre aux exigences du composant lui-même. Cela nécessiterait un composant personnalisé, capable de calculer l'échelle et de la peinture chaque image de l'image.

, Heureusement pour vous, JPanel est un ImageObserver, cela signifie qu'il est capable de la peinture de l'animation gif

Extensible

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
Author: MadProgrammer, 2018-04-14 00:42:43

J'ai fini par faire:

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

En utilisant revalidate et repaint de camickr, et la classe TestPane de MadProgrammer, ce qui a très bien fonctionné pour que le gif s'anime, se redimensionne correctement et s'affiche immédiatement.

 0
Author: Raymo111, 2018-04-14 01:04:41