Paul has posted 2 posts at DZone. You can read more from them at their website. View Full User Profile

Icon Manager for NetBeans Platform Applications

12.17.2013
| 2756 views |
  • submit to reddit

In this article I'd like to describe a solution to a problem that doesn't relate strictly to programming aspects of the NetBeans Platform, but more to user-related details, since programmers are also users. And in our case, they are users of the NetBeans Platform.

One of the usual routine tasks we have with the NetBeans Platform is to create some Action or Window or to integrate a new File Type. For these cases, NetBeans IDE gives us pretty nice wizards. But usually when I create some Window, I have no idea about what the related icon for it will be. And I can even say that I shouldn't care, since it's the designer, not the programmer, who should care about icons. Therefore, when finally the suitable icon is found, you want to change icons for other windows too, but all of them lie randomly in various source packages. As a result, you waste time and need to find various files and place various images in various places. This is just a simple example to show you how "not programmers" scenarios influence the development process.

Here is my approach to solve this situation. It is a simple and trivial Icon Manager but I hope that it could be helpful not only for me.

Lets have a look at the Node class from NetBeans Nodes API Tutorial:

"Copy the image linked above, or another 16x16 PNG or GIF, into the same package as the MyEditor class. Add the following method to the EventNode class."
...
@Override
public Image getIcon (int type) {
  return ImageUtilities.loadImage ("org/myorg/myeditor/icon.png");
}

@Override
public Image getOpenedIcon(int i) {
  return getIcon (i);
}
...

In this code ImageUtilities.loadImage loads icons only from the current module. You should be aware of the the icon folder in each module. Also you should also care about customization, such as image scaling and so on. Of course, you can do all the manipulation with Java2D in your Node class... but, you can do it even better and more efficiently with the Icon Manager that I describe below.

The structure of Icon Manager is very simple by default. It consists of two packages, "icons" and "iconmanager". In the icons folder there are 12 sub-folders (black, blue, brown, green, etc.). They are icon sets with different colors, which is useful if you need to customize your UI interaction behavior.

And now the Node class can be like this:

package ru.ptahi.aet.aetproject;

import java.awt.Image;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import ru.ptahi.iconmanager.IconManager;

public class ExampleNode extends FilterNode {

    private final String iconName = "lookup.png";

    public ExampleNode(Node original) {
        super(original);
    }

    @Override
    public Image getIcon(int type) {
        return IconManager.getActiveIcon(iconName);
    }

    @Override
    public Image getOpenedIcon(int type) {
        return IconManager.getOpenedIcon(iconName);
    }

}

Yes, right now it is almost the same as the standard approach, but be patient! When you need an icon not only for for the TreeView, you probably want a different size. Here is the related fragment from the IconManager:

public static java.awt.Image getIcon(String path, String iconName, int width, int height){
    IconManager currentIMObj = getIconManager();
    String key = path + iconName + width + height;
    if(!IconManager.mapAWT.containsKey(key)){
        currentIMObj.registerAWTImage(path, iconName, width, height);
    }
    return (java.awt.Image) IconManager.mapAWT.get(key);
}

You can manipulate width size, relative path, and the name of the image. All images are cached. Yes, IconManager uses ImageUtilities.loadImage() to load the image. But it has its own image cache.

Not convinced yet? Well, let see…

Here's a JavaFX component inside a TopComponent window and there is the same image in the TreeView and in the JavaFX component. Look below, the icon for the the Gender FX field is the same as the icon in the TreeView:



Here are the related methods:

public static javafx.scene.image.Image getFXIcon(String path, String iconName, int width, int height){...}

public static javafx.scene.image.Image getFXIcon(String iconName, int width, int height){...}

public static javafx.scene.image.Image getFXIcon(String iconName){...}

And the same example for JavaFX:

final ImageView participantGenderIcon = (ImageView) root.lookup("#participantGenderIcon");
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        final javafx.scene.image.Image imgFX1 = IconManager.getFXIcon("male-user.png");
        participantGenderIcon.setImage(imgFX1);
}
});

And one more:

ImageView icon = (ImageView) root.lookup("#icon");
icon.setImage(IconManager.getFXIcon("delete-item.png", 32, 32));

Of course, this is not a silver bullet and, as I mention at the start, it is not so much programming design as it is a usability approach for NetBeans Platform developers. It is available under GNU Lesser General Public License and can be found here:

https://www.dropbox.com/s/ub23ggnsfvk1em8/IconManager.zip

The icons, by Sarfraz Shoukat via gcons project, are free for personal and commercial designs and applications.

Published at DZone with permission of its author, Paul Orlov. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)