Translate

2017年2月2日木曜日

画像が更新されたことを知る

ImageListenerの実装

画像が更新されたときにOverlayを書き直したり、画像を新しく開いたり閉じたりした際に応答するためには ImageListenerを実装する。
Interface ImageListener
ImageListenerには3つのabstract methodsがある。それぞれ、
void    imageClosed(ImagePlus imp) 
void    imageOpened(ImagePlus imp) 
void    imageUpdated(ImagePlus imp) 
で、文字通り、imageClosedは画像が閉じたとき、imageOpenedは画像が開いたとき、imageUpdatedは画像が更新されたとき(例えばimp.updateAndDraw()が呼び出されたとき)に実行される。
このinterfaceはPluginのサブクラスやPluginFilterを実装するクラス(要はPluginのクラス)に実装するのではなく、
static void addImageListener(ImageListener listener) 
と、ImagePlusのクラスメソッドであるaddImageListenerで実装する。手っ取り早いのは、内部クラスとしてPluginの中で実装してしまう方法だ。
... Pluginのなんらかの処理

ImagePlus.addImageListener(new ImageListener() {

    @override
    public void imageClosed(ImagePlus imp) {
    //画像を閉じたときの処理
    }

    @override
    public void imageOpened(ImagePlus imp) {
    //画像を開いたときの処理
    }

    @override
    public void imageUpdated(ImagePlus imp) {
    //画像が更新されたときの処理
    }
}
ただ、こうすると、例えばPlugInFrameを閉じてもlistenerが残ったままになるので具合が悪い。
ImagePlusからlistenerを取り除くには、
static void ImagePlus.removeImageListener(ImageListener listener)
を実行すればよい。なので、ImageListnerを実装するときはこうしている。
public class hoge extends PlugInFrame {
    ...
    public static ImageListener listener;
    ...

    public hoge() {
        ...
        ImagePlus.addImageListener(new listener = ImageListener() {
            ... 
        }

        addWindowListener(new WindowAdapter() {
            @override
            public void windowClosing(WindowEvent e) {
                //フレームが閉じる時の処理
            }

            @override
            public void windowClosed(WindowEvent e) {
                //フレームが閉じたときの処理
                ImagePlus.removeImageListener(listener);
            }
        }
    }
}
まず、staticなメンバ変数としてlistenerを宣言している。そして
ImagePlus.addImageListener(new listner = ImageListener() {
とすることで、listenerをnewしている。別にちゃんとクラスを用意してもいいが、面倒くさいのでいつもこうしている。
WindowAdapterは、フレームが閉じたりするときの動作を記述することができるサブクラスで、addWindowListenerにそのサブクラスを継承するクラスを渡せばよい。これもいつも内部クラスで済ます。interfaceと違い、すべてのメソッドを実装する必要はない。
以上

0 件のコメント:

コメントを投稿