public class ScriptTest
{
public static void main(final String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
String language;
if (args.length == 0)
language = "js";
else
language = args[0];
// 脚本控制类
ScriptEngineManager manager = new ScriptEngineManager();
System.out.println("Available factories :");
for (ScriptEngineFactory factory : manager.getEngineFactories())
System.out.println(factory.getEngineName());
final ScriptEngine engine = manager.getEngineByName(language);
if (engine == null)
{
System.err.println("No engine for " + language);
System.exit(1);
}
ButtonFrame frame = new ButtonFrame();
try
{
// TODO 添加文件
File initFile = new File("init." + language);
if (initFile.exists())
{
engine.eval(new FileReader(initFile));
}
getComponentBindings(frame, engine);
final Properties events = new Properties();
// TODO 添加文件
InputStream in = ScriptTest.class.getResourceAsStream(language + ".properties");
events.load(in);
for (final Object e : events.keySet())
{
// 添加时间
String[] s = ((String)e).split("\\.");
addListener(s[0], s[1], (String)events.get(e), engine);
}
}
catch (Exception e)
{
e.printStackTrace();
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("ScriptTest");
frame.setVisible(true);
}
});
}
/** 把所有已命名的组件放在同一个容器中 */
private static void getComponentBindings(Component c, ScriptEngine engine)
{
String name = c.getName();
if (name != null)
engine.put(name, c);
if (c instanceof Container)
{
// 回调
for (Component child : ((Container)c).getComponents())
getComponentBindings(child, engine);
}
}
/** 为对象添加一个事件,监听到方法执行脚本 */
private static void addListener(String beanName, String eventName, final String scriptCode,
final ScriptEngine engine)
throws IllegalArgumentException, IntrospectionException, IllegalAccessException, InvocationTargetException
{
Object bean = engine.get(beanName);
EventSetDescriptor descriptor = getEventSetDescriptor(bean, eventName);
if (descriptor == null)
return;
descriptor.getAddListenerMethod().invoke(bean,
Proxy.newProxyInstance(null, new Class[] {descriptor.getListenerType()}, new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
engine.eval(scriptCode);
return null;
}
}));
}
private static EventSetDescriptor getEventSetDescriptor(Object bean, String eventName)
throws IntrospectionException
{
for (EventSetDescriptor descriptor : Introspector.getBeanInfo(bean.getClass()).getEventSetDescriptors())
if (descriptor.getName().equals(eventName))
return descriptor;
return null;
}
}
ButtonFrame类:
package script;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonFrame extends JFrame
{
private static final long serialVersionUID = 1L;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HELGHT = 200;
private JPanel panel;
private JButton yellowButton;
private JButton blueButton;
private JButton redButton;
public ButtonFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HELGHT);
panel = new JPanel();
panel.setName("panel");
add(panel);
yellowButton = new JButton("Yellow");
yellowButton.setName("yellowButton");
blueButton = new JButton("Blue");
blueButton.setName("blueButton");
redButton = new JButton("Red");
redButton.setName("redButton");
panel.add(yellowButton);
panel.add(blueButton);
panel.add(redButton);
}
}
js.properties
yellowButton.action=panel.background=java.awt.Color.YELLOW
blueButton.action=panel.background=java.awt.Color.BLUE
redButton.action=panel.background=java.awt.Color.RED