当前位置: 首页 > 面试题库 >

使jfilechooser显示图像缩略图

汲利
2023-03-14
问题内容

我想创建一个JFileChooser带有缩略图的图像文件视图,所以我将FileView子类化,并在创建方法中进行了ImageIcon一些缩放,以便显示缩略图图像。

但是,总体效果是,该filechooser小部件在打开目录并显示缩略图之前需要花费一些时间。在下面的createImageIcon()中,我需要两次调用new
ImageIcon()两次,分别使用图像文件路径和下一次调整大小的图像作为构造函数参数。我认为这是使小部件变慢的原因。

有没有更有效的选择?最欢迎您提出任何建议/指针。

谢谢,马克

public static void main(String[] args) { 
    JFileChooser chooser=new JFileChooser();
    ThumbNailView thumbView=new ThumbNailView();
    chooser.setFileView(thumbView);
  }

class ThumbNailView extends FileView{
 public Icon getIcon(File f){
  Icon icon=null;
  if(isImageFile(f.getPath())){
   icon=createImageIcon(f.getPath(),null);
  }
  return icon;
 }
 private ImageIcon createImageIcon(String path,String description) {
  if (path != null) {
   ImageIcon icon=new ImageIcon(path);
   Image img = icon.getImage() ; 
   Image newimg = img.getScaledInstance( 16, 16,  java.awt.Image.SCALE_SMOOTH ) ;
   return new ImageIcon(newimg);
  } else {
   System.err.println("Couldn't find file: " + path);
   return null;
   }
}

private boolean isImageFile(String filename){
    //return true if this is image
}

问题答案:

实际上,令我感到惊讶的是,尽管在Windows中使用了本机外观,但文件选择器确实没有缩略图视图。我尝试了您的示例,但您的做法正确无误,但我发现带有很多大图像的文件夹的速度很慢。当然,开销是由于读取文件内容然后解释图像时的I
/ O,这是不可避免的。

更糟糕的是,我发现这FileView.getIcon(File)被称为 很多
-在显示文件列表之前,将鼠标悬停在图标上以及更改选择内容时。如果我们在加载图像后不缓存图像,那么我们将一直无意义地重新加载图像。

显而易见的解决方案是将所有图像加载推到另一个线程或线程池上,一旦获得缩小的结果,就将其放入临时缓存中,以便可以再次对其进行检索。

我打得四处ImageImageIcon了很多,我发现了一个ImageIcon的图像可以在任何时候通过调用来改变setImage(Image)。对我们而言,这意味着在内getIcon(File),我们可以立即返回一个空白或默认图标,但保留对其的引用,并将其传递给工作线程,该线程将在后台加载图像,并在完成后设置图标的图像(唯一的不足是我们必须致电repaint()才能看到更改)。

对于此示例,我使用ExecutorService缓存的线程池(这是获取所有图像的最快方法,但是使用大量I / O)来处理图像加载任务。我还使用a
WeakHashMap作为缓存,以确保我们仅在需要它们时才保留它们。您可以使用另一种Map,但是必须管理持有的图标数量,以避免内存不足。

package guitest;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileView;

public class ThumbnailFileChooser extends JFileChooser {

    /** All preview icons will be this width and height */
    private static final int ICON_SIZE = 16;

    /** This blank icon will be used while previews are loading */
    private static final Image LOADING_IMAGE = new BufferedImage(ICON_SIZE, ICON_SIZE, BufferedImage.TYPE_INT_ARGB);

    /** Edit this to determine what file types will be previewed. */
    private final Pattern imageFilePattern = Pattern.compile(".+?\\.(png|jpe?g|gif|tiff?)$", Pattern.CASE_INSENSITIVE);

    /** Use a weak hash map to cache images until the next garbage collection (saves memory) */
    private final Map imageCache = new WeakHashMap();

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        JFileChooser chooser = new ThumbnailFileChooser();
        chooser.showOpenDialog(null);
        System.exit(1);
    }

    public ThumbnailFileChooser() {
        super();
    }

    // --- Override the other constructors as needed ---

    {
        // This initializer block is always executed after any constructor call.
        setFileView(new ThumbnailView());
    }

    private class ThumbnailView extends FileView {
        /** This thread pool is where the thumnnail icon loaders run */
        private final ExecutorService executor = Executors.newCachedThreadPool();

        public Icon getIcon(File file) {
            if (!imageFilePattern.matcher(file.getName()).matches()) {
                return null;
            }

            // Our cache makes browsing back and forth lightning-fast! :D
            synchronized (imageCache) {
                ImageIcon icon = imageCache.get(file);

                if (icon == null) {
                    // Create a new icon with the default image
                    icon = new ImageIcon(LOADING_IMAGE);

                    // Add to the cache
                    imageCache.put(file, icon);

                    // Submit a new task to load the image and update the icon
                    executor.submit(new ThumbnailIconLoader(icon, file));
                }

                return icon;
            }
        }
    }

    private class ThumbnailIconLoader implements Runnable {
        private final ImageIcon icon;
        private final File file;

        public ThumbnailIconLoader(ImageIcon i, File f) {
            icon = i;
            file = f;
        }

        public void run() {
            System.out.println("Loading image: " + file);

            // Load and scale the image down, then replace the icon's old image with the new one.
            ImageIcon newIcon = new ImageIcon(file.getAbsolutePath());
            Image img = newIcon.getImage().getScaledInstance(ICON_SIZE, ICON_SIZE, Image.SCALE_SMOOTH);
            icon.setImage(img);

            // Repaint the dialog so we see the new icon.
            SwingUtilities.invokeLater(new Runnable() {public void run() {repaint();}});
        }
    }

}

已知的问题:

1)缩放时,我们不保持图像的纵横比。这样做可能会导致图标的尺寸异常,从而破坏列表视图的对齐方式。解决方案可能是创建一个BufferedImage16x16
的新图像,并将缩放后的图像居中显示在其顶部。如果您愿意,可以实现它!

2)如果文件不是图像或已损坏,则完全不会显示任何图标。看起来程序仅在渲染图像时检测到此错误,而在加载或缩放图像时却未检测到,因此我们无法提前检测到此错误。但是,如果解决问题1,我们可能会检测到它。



 类似资料:
  • 我有一个jfilechooser,它帮助搜索和选择图像上传到项目数据库。还有一个缩略图类可以将上传的图像压缩成所需的大小。运行文件选择器的按钮action_performed的代码如下:

  • 我正在尝试使用一个菜单栏,使用户能够选择一个文件,并在JPanel中显示它,图像应该完全适合JPanel。但是JFileChooser在从对话框中成功选择文件时不会显示任何内容。我试着参考了许多链接:如何向JPanel添加图像?浏览图像文件并使用Java Swing显示它,但没有任何结果。请帮帮忙。以下是我的代码: 更新后的代码如下:

  • 本文向大家介绍使用ThinkPHP生成缩略图及显示,包括了使用ThinkPHP生成缩略图及显示的使用技巧和注意事项,需要的朋友参考一下 使用ThinkPHP生成缩略图及显示,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 首先了解父类Image.class.php(ThinkPHP/Library/Think/Image.class.php)中的一些函数 1:open() 打开被处理的图片 2:

  • 我正在学习这个教程。有了这个链接,你可以看到我对这个问题的评论。我遵循了这个教程,成功地在两个同龄人身上发送和接收短信。我还可以从控制台看到我的Firebase数据库及其更新。在这之前一切都很顺利。 现在,我想向Firebase发送/接收摄像头图像,所以我找到了各种方法将图像转换为Base64编码字符串,将该字符串上传到Firebase数据库,我在这方面也取得了成功。 我已成功将编码字符串上传到F

  • 问题内容: 我正在尝试在Django admin中显示缩略图,但是我只能看到图像的路径,而不能看到渲染的图像。我不知道我在做什么错。 服务器媒体网址: 功能型号: admin.py: 结果: 问题答案: 这是在photologue的来源中(请参阅,稍作修改以删除无关的内容): 该位看起来一样过了,我知道的作品。在我看来,唯一令人怀疑的是您的缩进-从代码末尾开始的两行 应与对齐:,如下所示:

  • 我正在尝试在一个自定义主题中实现wooCommerce,我正在基于bootstrap框架构建该主题(因为我对事物的外观很挑剔),所以我正在尝试重新定位wooCommerce产品缩略图库图像。我知道wooCommerce中提供的各种函数和钩子,如wc-template-hooks.php中列出的函数和钩子,它们工作得非常好,但在我的特殊情况下除外。我使用和钩子将产品信息包装在我的引导框架中,就像这样