Heim  >  Artikel  >  Java  >  Wie zeige ich mit SwingWorker ein Bild an, ohne die GUI einzufrieren?

Wie zeige ich mit SwingWorker ein Bild an, ohne die GUI einzufrieren?

Barbara Streisand
Barbara StreisandOriginal
2024-11-12 12:09:021019Durchsuche

How to Display an Image Without Freezing the GUI Using SwingWorker?

So zeigen Sie ein Bild an, ohne die GUI einzufrieren

Problem

Wenn auf eine Schaltfläche geklickt wird, wird ein Bild aus dem Web geladen und angezeigt ein Panel innerhalb eines anderen JFrame. Dies führt jedoch dazu, dass das Anwendungsfenster während des Bildladevorgangs vorübergehend einfriert.

Ursache

Das Problem tritt auf, weil die Abfrage der Schaltfläche im Event Dispatch Thread (EDT) ausgeführt wird. Dieser Thread ist für die Verarbeitung aller GUI-Updates verantwortlich. Wenn er also blockiert ist, reagiert die Anwendung nicht mehr.

Lösung: Verwendung von SwingWorker

Um ein Einfrieren zu vermeiden, sollte das Bild währenddessen im Hintergrund geladen werden Die GUI bleibt reaktionsfähig. Dies kann mit der Klasse javax.swing.SwingWorker erreicht werden.

SwingWorker ist eine Thread-sichere Klasse, die die Ausführung von Aufgaben im Hintergrund ermöglicht, ohne den EDT zu blockieren. Es bietet Methoden zum Festlegen der auszuführenden Aufgabe und zum anschließenden Ausführen in einem separaten Thread.

Implementierung

Hier ist ein Beispiel dafür, wie Sie mit SwingWorker ein Bild anzeigen können, ohne die GUI einzufrieren:

import java.util.concurrent.ExecutionException;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.net.URL;

public class ImageDisplaySwingWorker extends JFrame {

    private JLabel label = new JLabel("Loading...");

    public ImageDisplaySwingWorker() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        label.setHorizontalTextPosition(JLabel.CENTER);
        label.setVerticalTextPosition(JLabel.BOTTOM);
        this.add(label);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    private void start() {
        new ImageWorker().execute();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ImageDisplaySwingWorker imageDisplaySwingWorker = new ImageDisplaySwingWorker();
                imageDisplaySwingWorker.setVisible(true);
                imageDisplaySwingWorker.start();
            }
        });
    }

    class ImageWorker extends SwingWorker<Image, Void> {

        private static final String TEST = "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png";

        @Override
        protected Image doInBackground() throws IOException {
            Image image = ImageIO.read(new URL(TEST));
            return image.getScaledInstance(640, -1, Image.SCALE_SMOOTH);
        }

        @Override
        protected void done() {
            try {
                ImageIcon icon = new ImageIcon(get());
                label.setIcon(icon);
                label.setText("Done");
                ImageDisplaySwingWorker.this.pack();
                ImageDisplaySwingWorker.this.setLocationRelativeTo(null);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

In diesem Code:

  1. Eine Beschriftung wird verwendet, um die anzuzeigen Bild.
  2. Die start()-Methode wird aufgerufen, um den Bildladevorgang zu starten.
  3. Die ImageWorker-Klasse erweitert SwingWorker und definiert die doInBackground()-Methode, die das Bild in einen separaten Thread lädt.
  4. Die Methode done() wird aufgerufen, wenn das Laden des Bildes abgeschlossen ist. Es legt das Bild als Symbol für das Etikett fest und aktualisiert die GUI.

Das obige ist der detaillierte Inhalt vonWie zeige ich mit SwingWorker ein Bild an, ohne die GUI einzufrieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn