We help IT Professionals succeed at work.

How can I manage icon overlyaing in Windows with Java ?

gdancelli
gdancelli asked
on
Hi to all,

Is it possible to handle icon overlays in Windows from a Java app. ?
To better clarifiy, I have to reproduce what DropBox does on system icons, by adding some green checks, question marks, etc. on bottom right corner of each file icon handled by my app. depending on their status.
The icons overlay must be visible also from windows Explorer.
I know how to do it in C++ (a COM shell extension), but not in Java.

Thanks a lot.
Comment
Watch Question

Awarded 2011
Awarded 2011

Commented:
Are you talking about some say selection list of files in yoiur Java application ?

Author

Commented:
Yes.
In the beginning I planned to do something similar to a shell extension, the way that Windows actually handles icon overlays, but as I have to deal with multiplatform, it's probably better that I show the icons in a form of my java app. I can reproduce in java something similar to the Windows Explorer and then change the files icons in my app. only.
At this point, I need some information on how to retrieve from java the icons of the files in the folder that I'm inspecting and change  their icons by adding overlays according to a status.
Thanks.
Awarded 2011
Awarded 2011

Commented:
Are you using JFileChooser or your custom class to display files?
I'm not sure I understand what means "overlays" ?
If i understood u correct, then on OS file list screen, you want to modify the default file/folder icon, right.
If yes, then you already told that you know how to do in C++, so why not make a native code and call it from java using JNI.

http://jovial.com/javaAndCpp/java_and_cpp.html

Author

Commented:
Yes, I considered to call a native code from JNI, but as I have to deal with multiplatform, I was wondering if Java implements something similar without the aim of C++.
As it seems to be an operating system dependent feature (handling is different among various system), you must write different 'shell extensions' for each OS; that's not my goal.
At the end, I decided to show the folder icons in Java tree, where the file icons will be changed accordingly to a status; of course, outside the app. the system will show normal icons.
JFileChooser is not the right choice I believe as I need to reproduce a directory tree navigation only, showing files with their respective icons in a java form. No user action will be taken on that tree from Java, just display the correct files icons augmented with small bitmaps showing the file status (green checks, red crosses etc.), exactly like dropbox does.

Thanks.
Awarded 2011
Awarded 2011

Commented:
I don't think there is something which would not allow you to create such
display with icons and checkboxes using only Java with custom renderers,
and I don't think you'll need to use JNI for that purpose.
It will certainly take a bit of work, but seems to be doable.
Here is a sample of File System browser using JTree

Using custom cell renderer, i have customize the node image. You may change the node as per your condition.
import java.awt.*;
import java.io.File;
import java.util.Collections;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

/**
 * Display a file system in a JTree view
 * @author Pramod Kumar
 */
public class FileTree extends JPanel
{
    /**
     * Construct a FileTree
     */
    public FileTree(File dir)
    {
        setLayout(new BorderLayout());

        // Make a tree list with all the nodes, and make it a JTree
        JTree tree = new JTree(addNodes(null, dir));
        tree.setCellRenderer(new CustomTreeCellRenderer());
        // Add a listener
        tree.addTreeSelectionListener(new TreeSelectionListener()
        {
            public void valueChanged(TreeSelectionEvent e)
            {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) e
                        .getPath().getLastPathComponent();
                System.out.println("You selected " + node);
            }
        });

        // Lastly, put the JTree into a JScrollPane.
        JScrollPane scrollpane = new JScrollPane();
        scrollpane.getViewport().add(tree);
        add(BorderLayout.CENTER, scrollpane);
    }

    /**
     * Add nodes from under "dir" into curTop. Highly recursive.
     */
    DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir)
    {
        String curPath = dir.getPath();
        DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(curPath);
        if (curTop != null)
        { // should only be null at root
            curTop.add(curDir);
        }
        Vector ol = new Vector();
        String[] tmp = dir.list();
        for (int i = 0; i < tmp.length; i++)
        {
            ol.addElement(tmp[i]);
        }
        Collections.sort(ol, String.CASE_INSENSITIVE_ORDER);
        File f;
        Vector files = new Vector();
        // Make two passes, one for Dirs and one for Files. This is #1.
        for (int i = 0; i < ol.size(); i++)
        {
            String thisObject = (String) ol.elementAt(i);
            String newPath;
            if (curPath.equals("."))
            {
                newPath = thisObject;
            }
            else
            {
                newPath = curPath + File.separator + thisObject;
            }
            if ((f = new File(newPath)).isDirectory())
            {
                addNodes(curDir, f);
            }
            else
            {
                files.addElement(thisObject);
            }
        }
        // Pass two: for files.
        for (int fnum = 0; fnum < files.size(); fnum++)
        {
            curDir.add(new DefaultMutableTreeNode(files.elementAt(fnum)));
        }
        return curDir;
    }

    public Dimension getMinimumSize()
    {
        return new Dimension(200, 400);
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(200, 400);
    }

    /**
     * Main: make a Frame, add a FileTree
     */
    public static void main(String[] av)
    {

        JFrame frame = new JFrame("FileTree");
        frame.setForeground(Color.black);
        frame.setBackground(Color.lightGray);
        Container cp = frame.getContentPane();

        if (av.length == 0)
        {
            cp.add(new FileTree(new File(".")));
        }
        else
        {
            cp.setLayout(new BoxLayout(cp, BoxLayout.X_AXIS));
            for (int i = 0; i < av.length; i++)
            {
                cp.add(new FileTree(new File(av[i])));
            }
        }

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private static class CustomTreeCellRenderer extends DefaultTreeCellRenderer
    {
        ImageIcon rendererIcon;
        public void setRendererIcon(ImageIcon myIcon)
        {
            this.rendererIcon = myIcon;
        } ;

        public Component getTreeCellRendererComponent(JTree tree,
                                                      Object value, boolean selected, boolean expanded,
                                                      boolean leaf, int row, boolean hasFocus)
        {
            Component ret = super.getTreeCellRendererComponent(tree, value,
                    selected, expanded, leaf, row, hasFocus);
            JLabel label = (JLabel) ret;
            label.setIcon(new ImageIcon("icon.gif"));
            return ret;
        }
    }
}

Open in new window

icon.gif

Author

Commented:
Thanks a lot for sample code!