在Swing的开发中常常要给Swing的组件添加相关的事件监听,编译之后生成一堆class的内部类的文件。
采用注解可以简化,组件添加事件代码的杂乱。
注解类:
package com.easyway.commons.ispace.dev.advances.dbmeta; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 注解类 * @author longgangbai * @date 2010-5-15 * @version 1.0 * @since JDK6.0 */ @Target(ElementType.METHOD) //仅仅使用于方法 @Retention(RetentionPolicy.RUNTIME) //注解咋运行时,编译执行 public @interface ActionListenerFor { //注解针对的字段 String source(); }
注解使用的解析类:
package com.easyway.commons.ispace.dev.advances.dbmeta; import java.awt.event.ActionListener; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 运行时执行的相关的 注解代码 * @author longgangbai * @date 2010-5-15 * @version 1.0 * @since JDK6.0 */ public class ActionListenerInstaller { /** * 注解类的处理 * @param o */ public static void processAnnotation(Object o) { try { Class<?> cls=o.getClass(); for(Method m : cls.getDeclaredMethods()) { ActionListenerFor actionListener=m.getAnnotation(ActionListenerFor.class); if(actionListener!=null){ Field f=cls.getDeclaredField(actionListener.source()); boolean flag=f.isAccessible(); try{ if(!flag){ f.setAccessible(true); } addListener(f.get(o),o,m); }finally{ f.setAccessible(flag); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 采用代理的形式注入相关的方法 * @param source * @param param * @param m * @throws SecurityException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ public static void addListener(Object source,final Object param,final Method m) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ InvocationHandler handler=new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return m.invoke(param); } }; Object listener=Proxy.newProxyInstance(null,new Class[]{ActionListener.class}, handler); Method addr=source.getClass().getMethod("addActionListener", ActionListener.class); addr.invoke(source, listener); } }
SWing页面如下:
package com.easyway.commons.ispace.dev.advances.dbmeta; import java.awt.Button; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 注解的学习应用实例 * @author longgangbai * @date 2010-5-15 * @version 1.0 * @since JDK6.0 */ @SuppressWarnings("serial") public class SwingActionListenerJPanel extends JFrame{ private JPanel panel; private Button yellowButton; private Button blueButton; private Button redButton; private static final int DEFAULTWIDTH=400; private static final int DEFAULTHEIGHT=500; public SwingActionListenerJPanel() { setTitle("注解事件"); setSize(DEFAULTWIDTH,DEFAULTHEIGHT); panel=new JPanel(); add(panel); yellowButton=new Button("Yellow"); blueButton=new Button("blue"); redButton=new Button("red"); panel.add(yellowButton); panel.add(blueButton); panel.add(redButton); //注解的代码 ActionListenerInstaller.processAnnotation(this); } //注解的方法 @ActionListenerFor(source="redButton") public void redBackground(){ panel.setBackground(Color.RED); } @ActionListenerFor(source="blueButton") public void blueBackground(){ panel.setBackground(Color.BLUE); } @ActionListenerFor(source="yellowButton") public void yelllowBackground(){ panel.setBackground(Color.YELLOW); } }