gpt4 book ai didi

java - 使从服务器获取的图像实时显示

转载 作者:行者123 更新时间:2023-12-02 05:53:40 24 4
gpt4 key购买 nike

我有许多图像是通过一系列线程 HTTP 网络调用获取的。我正在使用 Callables 和 Futures 来管理这个过程。当每个图像从服务器返回时,我想将其显示在 JPanel 上,而不等待其他图像返回。

此代码有效,但在所有图像返回之前 UI 不会更新:

private void loadAndDisplayImages() throws InterruptedException, ExecutionException {      

final List<Callable<Image>> partitions = new ArrayList<Callable<Image>>();

for(final MediaFeedData data : imagesList) {
partitions.add(new Callable<Image>() {
public Image call() throws Exception {
String url = data.getImageUrl();
return ImageDisplayer.displayImageFromUrl(url, imageSize);
}
}
});
}

// for testing, use only a single thread to slow down rendering
final ExecutorService executorPool = Executors.newFixedThreadPool(1); //numImages);

// run each callable, capture the results in a list of futures
final List<Future<Image>> futureImages =
executorPool.invokeAll(partitions, 10000, TimeUnit.SECONDS);

for(final Future<Image> img : futureImages) {
Image image = img.get(); // this will block the UI

final ImageButton imageButton = new ImageButton(image, imageSize);

SwingUtilities.invokeLater(new Runnable(){
@Override public void run() {
imagesPanel.add(imageButton);
frame.validate();
frame.setVisible(true);
}
});
}

executorPool.shutdown();
}

最佳答案

考虑将 SwingWorkerExecutorService 结合使用...

SwingWorker...

    public class ImageLoaderWorker extends SwingWorker<Image, Image> {

private File source;
private JPanel container;

public ImageLoaderWorker(File source, JPanel container) {
this.source = source;
this.container = container;
}

@Override
protected Image doInBackground() throws Exception {
return ImageIO.read(source);
}

@Override
protected void done() {
try {
Image img = get();
JLabel label = new JLabel(new ImageIcon(img));
container.add(label);
container.revalidate();
container.repaint();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}

}

ExecutorService...

ExecutorService executor = Executors.newFixedThreadPool(4);
File images[] = new File("...").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".png");
}
});

for (File img : images) {

executor.submit(new ImageLoaderWorker(img, this));

}

可运行示例...

这只是扫描目录并加载图像,但概念基本相同......

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImageLoader {

public static void main(String[] args) {
new TestImageLoader();
}

public TestImageLoader() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel implements Scrollable {

public TestPane() {
setLayout(new GridLayout(0, 4));
ExecutorService executor = Executors.newFixedThreadPool(4);
File images[] = new File("...").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".png");
}
});

for (File img : images) {

executor.submit(new ImageLoaderWorker(img, this));

}
}

@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(600, 600);
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}

@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}

@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}

}

public class ImageLoaderWorker extends SwingWorker<Image, Image> {

private File source;
private JPanel container;

public ImageLoaderWorker(File source, JPanel container) {
this.source = source;
this.container = container;
}

@Override
protected Image doInBackground() throws Exception {
return ImageIO.read(source);
}

@Override
protected void done() {
try {
Image img = get();
JLabel label = new JLabel(new ImageIcon(img));
container.add(label);
container.revalidate();
container.repaint();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}

}

}

关于java - 使从服务器获取的图像实时显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56031045/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com