ImageDescriptorをゴリゴリとな。

こんな感じで、ロードするのは、どうでしょう?


ポイントは、Images,ImageDescriptors と言う
二つの、変なクラスを保持する型違いで、メンバ変数名は同じで作った上で、
そのメンバ変数名をキーに、実体のリソースファイル名を記述したpropertiesファイルを作ると、
それらを、まとめてロードしてくれるImageLoaderなるクラスがある事。

public class Images {
    public static Image DEFAULT_IMAGE;
}

public class ImageDescriptors {
    public static ImageDescriptor DEFAULT_IMAGE;
}

image.properties
DEFAULT_IMAGE=icons/sample.gif

public class ImageLoader {
    private ImageRegistry registry;
    public ImageLoader(ImageRegistry registry) {
        this.registry = registry;
    }
    public void loadResources(Class descHolder,Class imageHolder,String proppath) {
    // ごにょごにょ・・・
    }
}

これだと、使う時に結構楽な感じ。
入力補完は聴くし、リソースの論理名がとっちらからないけど、
実体のImageやImageDescriptorは、ImageRegistryが、後始末してくれるから、
怪しげな、リソース不足にはならずに済むですだよ。
どうです?id:y-komoriさん?


と、いう訳で、作ってみた。

public class BasicImageLoader implements ImageLoader {

    private ImageRegistry registry;

    public BasicImageLoader(ImageRegistry registry) {
        this.registry = registry;
    }

    public void loadResources(Class desc, Class image, String name) {
        ResourceBundle bundle = getBundle(name, desc.getClassLoader());
        if (bundle == null) {
            return;
        }
        BeanDesc descBd = BeanDescFactory.getBeanDesc(desc);
        BeanDesc imageBd = BeanDescFactory.getBeanDesc(image);
        if (descBd.getFieldSize() != imageBd.getFieldSize()) {
            return;
        }

        Map pathMap = ResourceBundleUtil.convertMap(bundle);
        for (int i = 0; i < descBd.getFieldSize(); i++) {
            Field descF = descBd.getField(i);
            String key = descF.getName();
            Field imgF = imageBd.getField(key);
            if (validateMask(descF) || validateMask(imgF)) {
                continue;
            }

            if (pathMap.containsKey(key) == false) {
                log(key + " not found in " + name);
                continue;
            }

            ImageDescriptor id = ImageDescriptor.createFromFile(desc, pathMap
                    .get(key).toString());
            this.getRegistry().put(key, id);
            FieldUtil.set(descF, null, id);
            FieldUtil.set(imgF, null, this.getRegistry().get(key));
        }
    }

    protected boolean validateMask(Field f) {
        final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
        final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
        return (f.getModifiers() & MOD_MASK) != MOD_EXPECTED;
    }

    protected void log(String msg) {
        // FIXME : FrameworkAdaptor とか、そんなん使う?
        System.out.println(msg);
    }

    protected ResourceBundle getBundle(String name, ClassLoader loader) {
        try {
            return ResourceBundle.getBundle(name, Locale.getDefault(), loader);
        } catch (MissingResourceException e) {
            return null;
        }
    }

    public ImageRegistry getRegistry() {
        return this.registry;
    }

    public void setRegistry(ImageRegistry registry) {
        this.registry = registry;
    }


作ってしまってから、気付いた事。
ロードする画像リソースが多くなると、全部メモリに展開しちゃうから、
このコード使って作られたプラグインを入れると、eclipseが重くなるやも…。
まぁ、その時は、その時で考えるって事で。