tags:

views:

54

answers:

3

I want to do one thing in Swing, I hope I will be clear enough.

I want to display a list of files with the icons, that the user have associated with that particular file, based on extension. However, I want this list of files be generated in the program - by that I mean: the displayed file icons will not be actual files in a folder (so I can't use JFileChooser).

Is there anything that can help me with this?

A: 

One ugly hack I just now thought of, I don't know if it will work.

I can create a temporary folder, then put empty files with the same filenames in there and then present a JFileChooser on that folder, then, after the window closes, delete that folder.

I would prefer a "cleaner" solution, though.

Karel Bílek
A: 

OK. This works well. I have taken ideas from this and this article.

The idea is, I create a classic JList, but I add a custom ListCellRenderer to paint the icons, which are taken from temporary files trough JFileChooser. The resulting renderer looks like this (I made the fields static, so they are not recreated each time the JList is made):

package app;

import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
public class PseudofileIconRenderer extends DefaultListCellRenderer {

    private static HashMap<String, Icon> extIcons = new HashMap<String, Icon>();
    private static Pattern p = Pattern.compile("\\.\\w+$");
    private static JFileChooser chooser = new JFileChooser();

    @Override
    public Component getListCellRendererComponent(
        JList list, Object value, int index,
        boolean isSelected, boolean cellHasFocus) {


    JLabel label =
            (JLabel) super.getListCellRendererComponent(list,
            value, index, isSelected, cellHasFocus);


    String filename = (String) value;
    Matcher m = p.matcher(filename);
    Icon i;
    String extension = m.find() ? m.group() : "";
    if (extIcons.containsKey(extension)) {
        i = extIcons.get(extension);
    } else  {
        File file;
        try {
            file = File.createTempFile("icon", extension);
            file.deleteOnExit();

            i = chooser.getIcon(file);
            extIcons.put(extension, i);

        } catch (IOException ex) {
            //this shouldn't happen anyway
            i = null;
        }
    }

    label.setIcon(i);

    return label;
}

I can, then, fill the JList with Strings, that will represent the files.

Karel Bílek
+1  A: 

Hi I came across this while googling... hop![alt text][1]e this helps:)

import java.io.; import javax.swing.;

public class IconExtract1 { public static void main(String[] args) throws Exception { String s = "c:/windows/regedit.exe"; File file = new File(s);

// Get metadata and create an icon
sun.awt.shell.ShellFolder sf =
        sun.awt.shell.ShellFolder.getShellFolder(file);
Icon icon = new ImageIcon(sf.getIcon(true));
System.out.println("type = " + sf.getFolderType());

// show the icon
JLabel ficon = new JLabel(s, icon, SwingConstants.LEFT);
JFrame frame = new JFrame();
frame.getContentPane().add(ficon);
frame.pack();
frame.setVisible(true);

} }

another way:

import java.io.; import javax.swing.; import java.awt.*; import javax.swing.filechooser.FileSystemView;

public class IconExtract2 { public static void main(String[] args) throws Exception { String s = "c:/windows/regedit.exe"; File file = new File(s);

// Get metadata and create an icon
Icon icon = FileSystemView.getFileSystemView().getSystemIcon(file);

// show the icon
JLabel ficon = new JLabel(s, icon, SwingConstants.LEFT);

JFrame frame = new JFrame();
frame.getContentPane().add(ficon);
frame.pack();
frame.setVisible(true);

} }

here is the link: http://www.rgagnon.com/javadetails/java-0439.html

Shwetanka
Oh, sorry, I read it wrong. This, for some reason, doesn't work in OS X - it returns the same icon for each file. The solution in my own answer works there.
Karel Bílek