首页  >  文章  >  Java  >  如何使用 SwingWorker 显示图像而不冻结 GUI?

如何使用 SwingWorker 显示图像而不冻结 GUI?

Barbara Streisand
Barbara Streisand原创
2024-11-12 12:09:021024浏览

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

如何在不冻结 GUI 的情况下显示图像

问题

单击按钮时,将从网络加载图像并显示在另一个 JFrame 中的面板。但是,这会导致应用程序窗口在图像加载过程中暂时冻结。

原因

出现此问题的原因是按钮的查询是在事件调度线程 (EDT) 上执行的。该线程负责处理所有 GUI 更新,因此当它被阻塞时,应用程序将变得无响应。

解决方案:使用 SwingWorker

为避免冻结,应在后台加载图像,同时GUI 保持响应。这可以使用 javax.swing.SwingWorker 类来实现。

SwingWorker 是一个线程安全的类,允许在后台执行任务而不会阻塞 EDT。它提供了设置要执行的任务,然后在单独的线程中执行它的方法。

实现

下面是如何使用 SwingWorker 在不冻结 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();
            }
        }
    }
}

在此代码中:

  1. 标签用于显示图像。
  2. 调用 start() 方法来启动图像加载过程。
  3. ImageWorker 类扩展了 SwingWorker 并定义了 doInBackground() 方法,该方法在单独的线程中加载图像。
  4. done() 方法在图像加载完成时被调用。它将图像设置为标签的图标并更新 GUI。

以上是如何使用 SwingWorker 显示图像而不冻结 GUI?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn