7
votes

Making jfilechooser show image vignettes

Je voulais créer un jfilechooser avec la vue de la vignette de l'image Files.so I Sous-classement FileView et dans la méthode qui crée imageicon a fait une étalage des images vignettes.

Toutefois, l'effet global est que, le widget filechooser prend un certain temps avant d'ouvrir un répertoire et de montrer des vignettes..en CreateImageIcon () ci-dessous, j'ai besoin d'appeler nouvelle imageicon () deux fois Avec l'image FilePath et ensuite avec l'image redimensionnée comme argument de constructeur.Je pense que c'est ce que c'est ce qui ralentit le widget.

existe une alternative plus efficace? Toute suggestion / pointeurs le bienvenue.

merci, Mark xxx


0 commentaires

3 Réponses :


0
votes

Vous pouvez utiliser une icône par défaut pour chaque fileand charger les icônes réelles dans un autre fil (peut-être utiliser un swingworker?). Comme les icônes sont chargées, SwingWorker pourrait rappeler et mettre à jour le fichier FileView.

Je ne sais pas si un seul swingworker ferait le tour ou s'il serait préférable d'utiliser un pour chaque icône chargée.


0 commentaires

10
votes

J'étais en fait surpris de voir que, malgré l'utilisation de l'apparence natale et de la sensation de Windows, le choix de fichiers n'a en effet pas une vue miniature. J'ai essayé votre exemple et vous suivez les bonnes lignes, mais je vois à quel point il était lent pour les dossiers avec beaucoup de grandes images. Les frais généraux sont bien entendus en raison d'E / S lors de la lecture du contenu du fichier, puis d'interpréter l'image inévitable.

Qu'est-ce qui est encore pire, c'est que j'ai découvert que fileview.geticon (fichier) est appelé A LOT B> - Avant que la liste des fichiers ne soit affichée, lorsque vous passez la souris sur une icône et lorsque la sélection change. Si nous ne mettrions pas en cache les images après les charger, nous rechargons sans point d'inutilité des images tout le temps. P>

La solution évidente consiste à appuyer sur toute l'image de chargement sur un autre fil ou une piscine de thread. Une fois que nous avons notre résultat échoué, mettez-le dans un cache temporaire afin qu'il puisse être récupéré à nouveau. P>

J'ai joué avec image code> et imageicon code> Beaucoup et j'ai découvert qu'un imageicon code> S peut être modifié à tout moment en appelant SetImage (image) code>. Ce que cela signifie pour nous est, dans geticon (fichier) code>, nous pouvons immédiatement renvoyer une icône vierge ou par défaut, mais conserver une référence, la transmettre à un fil de travail qui chargera l'image dans l'arrière-plan et définissez l'image de l'icône plus tard quand c'est fait (la seule prise est que nous devons appeler repeindre () code> pour voir le changement). P>

pour cet exemple, je suis Utilisation d'un pool de threads code> ExecuTertorservice Code> Cached (Ceci est le moyen le plus rapide d'obtenir toutes les images, mais utilise beaucoup d'E / S) pour traiter les tâches de chargement d'images. J'utilise également un faiblesHashmap code> comme cache, pour vous assurer que nous ne tenons que sur les icônes en cache aussi longtemps que nous en avons besoin. Vous pouvez utiliser un autre type de carte, mais vous devrez gérer le nombre d'icônes que vous maintenez pour éviter de manquer de mémoire. P>

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();}});
        }
    }

}


0 commentaires

5
votes

Utiliser filedialog code> au lieu de jfilechooser code> pour choisir l'image:

FileDialog fd = new FileDialog(frame, "Test", FileDialog.LOAD);
String Image_path

fd.setVisible(true);
name = fd.getDirectory() + fd.getFile();
        image_path=name;
        ImageIcon icon= new ImageIcon(name);
        icon.setImage(icon.getImage().getScaledInstance(jLabel2.getWidth(),jLabel2.getHeight() , Image.SCALE_DEFAULT));
        jLabel2.setIcon(icon);


1 commentaires

Suggérer AWT dans une question de swing en 2012? Eww ...