單擊按鈕時,將從網絡加載圖像並顯示在另一個JFrame 中的面板。但是,這會導致應用程式視窗在圖像載入過程中暫時凍結。
出現此問題的原因是按鈕的查詢是在事件調度執行緒 (EDT) 上執行的。該線程負責處理所有 GUI 更新,因此當它被阻塞時,應用程式將變得無響應。
為避免凍結,應在後台載入影像,同時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(); } } } }
在此程式碼中:
以上是如何使用 SwingWorker 顯示影像而不凍結 GUI?的詳細內容。更多資訊請關注PHP中文網其他相關文章!