EventListenerの拡張

最近やっと時間ができたのでS2JFaceをいろいろいじってみている。サンプルやソースを見ながら簡単なGUIを作ったんだけど、今はイベントがSelectionしか取れなくって少し物足りない。そこで試行錯誤しながらも少し拡張してみた。

EventListenerTypeを変更。

package org.seasar.jface.annotation;

import java.util.StringTokenizer;

import org.seasar.framework.util.StringUtil;
import org.seasar.jface.util.SWTUtil;

/**
 * @author y-komori
 * 
 */
public enum EventListenerType {
    
    // ArmListener
    ARM,
    
    // ControlListener
    MOVE, RESIZE,
    
    // DisposeListener
    DISPOSE,
    
    // FocusListener
    FOCUS_IN, FOCUS_OUT,
    
    // HelpListener
    HELP,
    
    // KeyListener
    KEY_PRESSED, KEY_RELEASED,
    
    // MenuListener
    HIDE, SHOW,
    
    // ModifyListener
    MODIFY, 
    
    // MouseListener
    MOUSE_DOUBLE_CLICK, MOUSE_DOWN, MOUSE_UP,
    
    // MouseMoveListener
    MOUSE_MOVE,
    
    // MouseTrackListener
    MOUSE_ENTER, MOUSE_EXIT, MOUSE_HOVER,
    
    // PaintListener
    PAINT,
    
    // SelectionListener
    DEFAULT_SELECTION, SELECTION,
    
    // ShellListener
    ACTIVATE, CLOSE, DEACTIVATE, DEICONIFY, ICONIFY,
    
    // TraverseListener
    TRAVERSE,
    
    // TreeListener
    COLLAPSE, EXPAND,
    
    // VerifyListener
    VERIFY;

    public String getName() {
        return toString().toLowerCase();
    }

    // TODO 面倒でもSWT.Xxxを直接参照した方がコンパイルエラーになってよいかも
    public int getSWTEventType() {
        String swtConstantName = capitalizeConstantName(toString());
        return SWTUtil.getSWTConstant(swtConstantName);
    }

    // TODO 適切なクラスに移動する
    private String capitalizeConstantName(String string) {
        StringTokenizer st = new StringTokenizer(string, "_");
        StringBuilder builder = new StringBuilder("");
        while (st.hasMoreTokens()) {
            builder.append(StringUtil.capitalize(st.nextToken().toLowerCase()));
        }
        return builder.toString();
    }
}

MethodBindingSupport.javaの85行目くらい。Listener登録部分を修正。

Listener listener = ListenerFactory.getListener(context, methodBinding);
ListenerBinder.bindListener(listenerType, listener, widget);

S2JFaceListenerを新規に追加(S2JFaceSelectionListenerなどの代わり)。

package org.seasar.jface.events;

import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.seasar.jface.WindowContext;
import org.seasar.jface.binding.MethodBinding;
import org.seasar.jface.binding.WidgetBinder;

public class S2JFaceListener implements Listener {
    
    private WindowContext context;

    private MethodBinding methodBinding;

    public S2JFaceListener(WindowContext context, MethodBinding methodBinding) {
        this.context = context;
        this.methodBinding = methodBinding;
    }

    public void handleEvent(Event event) {
        if (methodBinding != null) {
            WidgetBinder.bindWidgets(methodBinding.getTarget(), context);
            methodBinding.invoke();
        }
    }
    
}

ListenerBinderはS2JFaceListenerをnewしてるだけだし、ListnerBinderはWidget#addListenerを呼んでるだけなので省略。
これで大抵のイベントでメソッドを呼び出せるようになった。こんなやり方でいいのかはわからんけれど、やればできるもんだなぁ。