Maison  >  Article  >  Java  >  Comment afficher une image sans geler l'interface graphique à l'aide de SwingWorker ?

Comment afficher une image sans geler l'interface graphique à l'aide de SwingWorker ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-12 12:09:021019parcourir

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

Comment afficher une image sans geler l'interface graphique

Problème

Lorsque vous cliquez sur un bouton, une image est chargée depuis le Web et affichée dans un panneau dans un autre JFrame. Cependant, cela provoque le gel momentané de la fenêtre de l'application pendant le processus de chargement de l'image.

Cause

Le problème survient car la requête du bouton est exécutée sur le thread de répartition d'événements (EDT). Ce fil est responsable de la gestion de toutes les mises à jour de l'interface graphique, donc lorsqu'il est bloqué, l'application ne répond plus.

Solution : Utilisation de SwingWorker

Pour éviter le gel, l'image doit être chargée en arrière-plan pendant l'interface graphique reste réactive. Ceci peut être réalisé en utilisant la classe javax.swing.SwingWorker.

SwingWorker est une classe thread-safe qui permet l'exécution de tâches en arrière-plan sans bloquer l'EDT. Il fournit des méthodes pour définir la tâche à exécuter, puis l'exécuter dans un thread séparé.

Implémentation

Voici un exemple de la façon d'utiliser SwingWorker pour afficher une image sans geler l'interface graphique :

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

Dans ce code :

  1. Une étiquette est utilisée pour afficher l'image.
  2. La méthode start() est appelée pour lancer le processus de chargement de l'image.
  3. La classe ImageWorker étend SwingWorker et définit la méthode doInBackground() qui charge l'image dans un thread séparé.
  4. La méthode done() est appelée lorsque le chargement de l'image est terminé. Il définit l'image comme icône de l'étiquette et met à jour l'interface graphique.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn