Zeigen Sie einen animierten BG in Swing

Lesezeit: 5 Minuten

Zeigen Sie einen animierten BG in Swing
Andreas Thompson

Ein animiertes (radelndes) GIF kann in einem angezeigt werden JLabel oder in HTML (in formatierten Textkomponenten wie z JEditorPane) und beim Radfahren gesehen werden.

Aber um ein Bild zu laden, das als Hintergrund eines Containers gezeichnet werden soll, würde ich normalerweise beides verwenden ImageIO.read() oder Toolkit.getImage() (Letzteres, wenn ich mich nostalgisch für das letzte Jahrtausend fühle). Keine Methode zum Laden eines Bildes führt zu einem zyklischen Bild, es ist normalerweise nur das erste Bild.

So laden Sie eine animiert Bild als Hintergrund?

Z.B

1646781435 23 Beispielbilder fur Fragen und Antworten zu Code und Markup closed

Zeigen Sie einen animierten BG in Swing
Andreas Thompson

Um ein radfahrendes (animiertes) GIF zum benutzerdefinierten Malen zu erhalten, besteht ein Trick darin, es mit einem zu laden ImageIcon. Während das Bild, das von einer der beiden in der Frage aufgeführten Methoden zurückgegeben wird, statisch ist, wird eines von einer ImageIcon ist animiert.

Der folgende Code fügt 50 Schaltflächen hinzu, kurz danach die Frames des animierten GIFs „Zooming Stars“.1 als BG zu ihnen. Die ImagePanel dehnt das Bild auf die Größe des Panels.

  1. Es basiert auf diesem Bild.

Zoomende Sterne GIF

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;

class ImagePanel extends JPanel {

    private Image image;

    ImagePanel(Image image) {
        this.image = image;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image,0,0,getWidth(),getHeight(),this);
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://i.stack.imgur.com/iQFxo.gif");
        final Image image = new ImageIcon(url).getImage();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("Image");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                ImagePanel imagePanel = new ImagePanel(image);
                imagePanel.setLayout(new GridLayout(5,10,10,10));
                imagePanel.setBorder(new EmptyBorder(20,20,20,20));
                for (int ii=1; ii<51; ii++) {
                    imagePanel.add(new JButton("" + ii));
                }

                f.setContentPane(imagePanel);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

  • Vielen Dank für dieses nette SSCCE, ich wusste nicht, dass ImageIcon die Animation einer .gif-Datei anzeigen kann. Ich habe überlegt, ob ich meiner GUI ein animiertes Bild hinzufügen soll, und jetzt weiß ich, dass es ziemlich einfach sein wird, wenn ich es hinzufügen möchte.

    – WilliamShatner

    26. Februar 2013 um 15:44 Uhr

Zeigen Sie einen animierten BG in Swing
kschneid

Verwenden ImageIcon ist wohl das einfachste was man machen kann. Ein paar Dinge, die Sie beachten sollten:

  • ImageIcon(URL) selbst nutzt Toolkit.getImage(URL). Sie können es vorziehen, zu verwenden Toolkit.createImage(URL) stattdessen – getImage() kann zwischengespeicherte oder freigegebene Bilddaten verwenden.

  • ImageIcon nutzt a MediaTracker um effektiv zu warten, bis das Bild vollständig geladen ist.

Ihr Problem ist also möglicherweise nicht die Verwendung von Toolkit (ImageIO ist ein anderes Biest), sondern die Tatsache, dass Sie kein vollständig geladenes Bild rendern. Eine interessante Sache zum Ausprobieren wäre:

Image image = f.getToolkit().createImage(url);
//...
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.prepareImage(image, imagePanel);
//...

Mein Swing/AWT/J2D ist vielleicht etwas verschwommen, aber die Idee ist, dass seit Ihrem ImagePanel ist ein ImageObserver, kann es asynchron über Bildinformationen benachrichtigt werden. Die Component.imageUpdate() Methode aufrufen soll repaint wie benötigt.

Bearbeiten:

Wie in den Kommentaren vermerkt, der Aufruf an prepareImage ist nicht erforderlich – ein funktionierendes Beispiel ist unten enthalten. Der Schlüssel ist, dass die überschrieben paintComponent Methode aufruft Graphics.drawImagedie die liefert ImageObserver Haken. Die imageUpdate Methode (implementiert in java.awt.Component) wird kontinuierlich mit aufgerufen ImageObserver.FRAMEBITS Flagge gesetzt.

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class ImagePanel extends JPanel {

    private final Image image;

    public ImagePanel(Image image) {
        super();
        this.image = image;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(this.image, 0, 0, getWidth(), getHeight(), this);
    }

    public static void main(String[] args) throws MalformedURLException {
        final URL url = new URL("http://i.stack.imgur.com/iQFxo.gif");
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame("Image");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                Image image = f.getToolkit().createImage(url);
                ImagePanel imagePanel = new ImagePanel(image);
                imagePanel.setLayout(new GridLayout(5, 10, 10, 10));
                imagePanel.setBorder(new EmptyBorder(20, 20, 20, 20));
                for (int ii = 1; ii < 51; ii++) {
                    imagePanel.add(new JButton("" + ii));
                }

                f.setContentPane(imagePanel);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

  • Großer Fang. Geprüft Toolkit.createImage(URL) als direkter ‘Drop-in’-Ersatz für new ImageIcon(url).getImage() & das Bild radelte auch. Beachten Sie, dass ich mich nicht die Mühe gemacht habe, anzurufen prepareImage.

    – Andrew Thompson

    1. Juni 2012 um 3:38 Uhr

  • Ich werde meine Antwort morgen bearbeiten, aber mir ist auch aufgefallen, dass der von mir erstellte Test (eine modifizierte Version Ihres Codes) den Aufruf „prepareImage“ nicht erforderte. Ich glaube, dass der Aufruf von Graphics.drawImage den ImageObserver-Hook bereitstellt …

    – kschneid

    1. Juni 2012 um 4:06 Uhr

  • Habe die Bearbeitung erst jetzt bemerkt. Ich dachte, dies könnte meine erste kanonische Frage und Antwort sein, aber es stellt sich heraus, dass Ihre Antwort besser ist! Ich bin mir nicht sicher, ob ich irritiert sein soll, übertrumpft zu werden, oder ob ich mich freuen soll, jemanden mit mehr Details zu finden. (überlegt noch ein paar Augenblicke…) OK, freut mich. Danke für deine Antwort. 🙂

    – Andrew Thompson

    2. Juni 2012 um 7:30 Uhr

Ich habe es geschafft, das animierte GIF auf diese Weise in mein JPanel zu bekommen:

private JPanel loadingPanel() {
    JPanel panel = new JPanel();
    BoxLayout layoutMgr = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
    panel.setLayout(layoutMgr);

    ClassLoader cldr = this.getClass().getClassLoader();
    java.net.URL imageURL   = cldr.getResource("img/spinner.gif");
    ImageIcon imageIcon = new ImageIcon(imageURL);
    JLabel iconLabel = new JLabel();
    iconLabel.setIcon(imageIcon);
    imageIcon.setImageObserver(iconLabel);

    JLabel label = new JLabel("Loading...");
    panel.add(iconLabel);
    panel.add(label);
    return panel;
}

Einige Punkte dieses Ansatzes:
1. Die Bilddatei befindet sich im Glas;
2. ImageIO.read() gibt ein BufferedImage zurück, das den ImageObserver nicht aktualisiert;
3. Eine weitere Alternative, um Bilder zu finden, die in der JAR-Datei gebündelt sind, besteht darin, den Java-Klassenlader, den Code, der Ihr Programm geladen hat, zu bitten, die Dateien abzurufen. Es weiß, wo die Dinge sind.

Auf diese Weise konnte ich mein animiertes GIF in mein JPanel bekommen und es funktionierte wie ein Zauber.

1000950cookie-checkZeigen Sie einen animierten BG in Swing

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy