Home  >  Article  >  Java  >  How to Display an Image Without Freezing the GUI Using SwingWorker?

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

Barbara Streisand
Barbara StreisandOriginal
2024-11-12 12:09:021024browse

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

How to Display an Image Without Freezing the GUI

Problem

When a button is clicked, an image is loaded from the web and displayed in a panel within another JFrame. However, this causes the application window to freeze momentarily during the image loading process.

Cause

The issue arises because the button's query is executed on the event dispatch thread (EDT). This thread is responsible for handling all GUI updates, so when it's blocked, the application becomes unresponsive.

Solution: Using SwingWorker

To avoid the freezing, the image should be loaded in the background while the GUI remains responsive. This can be achieved using the javax.swing.SwingWorker class.

SwingWorker is a thread-safe class that allows for the execution of tasks in the background without blocking the EDT. It provides methods for setting the task to be executed and then executing it in a separate thread.

Implementation

Here's an example of how to use SwingWorker to display an image without freezing the GUI:

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 this code:

  1. A label is used to display the image.
  2. The start() method is called to initiate the image loading process.
  3. The ImageWorker class extends SwingWorker and defines the doInBackground() method that loads the image in a separate thread.
  4. The done() method is called when the image loading is complete. It sets the image as the icon for the label and updates the GUI.

The above is the detailed content of How to Display an Image Without Freezing the GUI Using SwingWorker?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn