jdesktop的Application Framework -- Java 桌面应用程序的一个框架
使用@Action绑定事件到某个函数时,可以设置若干参数,函数被框架执行的时候将填充这些参数。下面是从源码中拷来的:
1、Action的入口函数:
如果不是代理的action就执行noProxyActionPerformed(actionEvent);
public void actionPerformed(ActionEvent actionEvent) {
javax.swing.Action proxy = getProxy();
if (proxy != null) {
actionEvent.setSource(getProxySource());
proxy.actionPerformed(actionEvent);
}
else if (actionMethod != null) {
noProxyActionPerformed(actionEvent);
}
}
2、执行事件绑定的函数:
private void noProxyActionPerformed(ActionEvent actionEvent) {
Object taskObject = null;
/* Create the arguments array for actionMethod by
* calling getActionArgument() for each parameter.
*/
Annotation[][] allPAnnotations = actionMethod.getParameterAnnotations();
Class<?>[] pTypes = actionMethod.getParameterTypes();
Object[] arguments = new Object[pTypes.length];
for(int i = 0; i < pTypes.length; i++) {
String pKey = null;
for(Annotation pAnnotation : allPAnnotations[i]) {
if (pAnnotation instanceof Action.Parameter) {
pKey = ((Action.Parameter)pAnnotation).value();
break;
}
}
arguments[i] = getActionArgument(pTypes[i], pKey, actionEvent);
}
/* Call target.actionMethod(arguments). If the return value
* is a Task, then execute it.
*/
try {
Object target = appAM.getActionsObject();
taskObject = actionMethod.invoke(target, arguments);
}
catch (Exception e) {
actionFailed(actionEvent, e);
}
if (taskObject instanceof Task) {
Task task = (Task)taskObject;
if (task.getInputBlocker() == null) {
task.setInputBlocker(createInputBlocker(task, actionEvent));
}
ApplicationContext ctx = appAM.getContext();
ctx.getTaskService().execute(task);
}
}
3、获取调用参数的方法:
Object org.jdesktop.application.ApplicationAction.getActionArgument(Class pType, String pKey, ActionEvent actionEvent)
Provides parameter values to @Action methods. By default, parameter values are selected based exclusively on their type:
Parameter TypeParameter Value
ActionEvent |
actionEvent |
javax.swing.Action |
this ApplicationAction object |
ActionMap |
the ActionMap that contains this Action |
ResourceMap |
the ResourceMap of the the ActionMap that contains this Action |
ApplicationContext |
the value of ApplicationContext.getInstance() |
ApplicationAction subclasses may also select values based on the value of the Action.Parameter annotation, which is passed along as the pKey argument to this method:
@Action public void doAction(@Action.Parameter("myKey") String myParameter) {
// The value of myParameter is computed by:
// getActionArgument(String.class, "myKey", actionEvent)
}
If pType and pKey aren't recognized, this method calls actionFailed
with an IllegalArgumentException.
Parameters: pType parameter type pKey the value of the @Action.Parameter annotation actionEvent the ActionEvent that trigged this Action
protected Object getActionArgument(Class pType, String pKey, ActionEvent actionEvent) {
Object argument = null;
if (pType == ActionEvent.class) {
argument = actionEvent;
}
else if (pType == javax.swing.Action.class) {
argument = this;
}
else if (pType == ActionMap.class) {
argument = appAM;
}
else if (pType == ResourceMap.class) {
argument = resourceMap;
}
else if (pType == ApplicationContext.class) {
argument = appAM.getContext();
}
else if (pType == Application.class) {
argument = appAM.getContext().getApplication();
}
else {
Exception e = new IllegalArgumentException("unrecognized @Action method parameter");
actionFailed(actionEvent, e);
}
return argument;
}
代码示例:
1.没有参数
@Action
public void search() {
// your code...
}
2. 带ActionEvent参数,获得参数的能力等同写在ActionListener里面了
@Action
public void search(ActionEvent e) {
// your code...
}
3.带ResourceMap,这个比较实用,可以直接取到这个类的资源映射表
@Action
public void search(ResourceMap resourceMap, ActionEvent e) {
// your code...
}
补充一下,一个Application可以有多个Resource文件。如果存在一个和类同名的properties文件,则这个被认为是此类的资源文件,否则使用这个Application的资源文件。这种组织方式比较好,可以将资源分散到调用类的资源文件里定义,方便维护,结构清晰。
4.其它参数类似,只要类型匹配就行,顺序没关系!!
ApplicationAction类还不支持@Action.Parameter,程序中没处理,但这个可以很方便扩展。
总结:
使用@Action绑定事件到某个函数,这不但可以获取原来所需的参数,而且还可以方便的获得Application的相关参数,也支持扩展。
极力推荐使用这种方式编写Swing的事件处理,再也不用写n个Action了,或是那些看到麻木的new ActionListener(ActionEvent e){......}
分享到:
相关推荐
Java Swing组件:Jlist学习笔记Java Swing组件:Jlist学习笔记
Java swing 知识总结学习笔记,全面总结了在Java学习中关于Swing的相关知识。
这是Swing应用程序框架(JSR 296)的分支。 BSAF项目的官方主页位于http://kenai.com/projects/bsaf-所有源代码存储库,讨论列表,论坛和资源都在Kenai托管。
用于java swing编程的jar包。图形界面编程使用,缺此jar包的可以下载。
NULL 博文链接:https://huangrongyou.iteye.com/blog/1610287
主题:Swing是一把刀 http://www.iteye.com/topic/702804 主题:Swing第二刀:枝间新绿一重重 http://www.iteye.com/topic/707540 主题:Swing第二小刀刀:星星之火可以燎原 http://www.iteye.com/topic/707514 ...
java swing界面调用本地摄像头,demo可以直接导入eclipse运行,直接运行CameraFrame.java即可。
杰地桌面应用框架 Desktop Application Framework 对于大多数开发人员来说,做一个小的Swing应用程序很容易。用JFrame和大多数Swing组件都不难。再加上JIDE提供的一些组件,把它们都用在一起也还行。可是,当您的...
Swing读书笔记,Swing读书笔记,Swing读书笔记
java swing 笔记
深入学习:JFC Swing
比较经典的Swing书。PDF版本,因为文件太大分为两部分。
Java 配对小游戏 Swing + MigLayout ## 文件简介 * source: 程序源代码 * matchingGame.jar: 可运行jar包 * report.pdf: 开发流程报告 ## 运行环境 Jave SE 8 ## 如何运行(两种方法) * 双击matchingGame.jar * ...
跨平台使用swing调用浏览器,由于现在很多的机器的jre或者jdk都是1.5版本及以下的不能使用jdk 1.6 desktop类。
java图形编程:Action接口(Swing新增功能)专题借鉴.pdf
Java语言是当前最流行的编程语言。国际上,在选择编程语言时,无论是编程者还是决策者都会首选Java,因为其...类、接口和构造函数,各个类和接口中的子类、方法、合法参数等等。可以说本书是Java编程方面的高层专业书。
2、调用prepareSplash()函数,初始化启动界面 private void prepareSplash() { Toolkit toolkit = Toolkit.getDefaultToolkit(); windowSplash = new Window( this ); Image image = ...
深入学习:JFC SWING—JAVA 基础类组件集 深入学习:JFC SWING—JAVA 基础类组件集
java swing 开发的向导对话框,纯JAVA开发包,简单实用
非常有用的学习资料,值得初学者看 对于窗口的设计,都很好