首頁  >  文章  >  Java  >  如何使用 SwingWorker 顯示影像而不凍結 GUI?

如何使用 SwingWorker 顯示影像而不凍結 GUI?

Barbara Streisand
Barbara Streisand原創
2024-11-12 12:09:021092瀏覽

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