Adding Context Sensitivity. 16
使用 Netbean 进行 Spring rcp 程序开发
Getting Started
1. 安装Spring rcp tools插件到Netbean IDE;
2. 在新建工程向导里,可以找到新的模板工程:
3. 完成向导工程会得到下面的工程文件结构:
文件总览:
文件名称 | 描述 |
SimpleApp.java | 提供了应用程序的“main”函数,并且通过Spring rcp的“ApplicationLauncher”类启动应用程序。该类加载application context XML文件和startup context XML文件,这两个文件负责“程序级别”的功能,如欢迎窗口,初始化顺序,和定义的视图。 |
SimpleLifecycleAdvisor.java | 提供应用程序的生命周期管理。该类被注册在application context XML文件。它提供了诸如“onWindowOpened”和“onCommandsCreated”等方法,使得你在应用程序启动是拥有了个性化定制的切入点。(比如,你可以在“onPreWindowOpen”函数中调整应用程序的尺寸)。 |
richclient-application-context.xml | 提供了application context XML文件,该文件配置了Spring RCP的组件和服务。 |
richclient-startup-context.xml | 提供了startup context XML文件,该文件定义了欢迎窗口,但是也可以定义任何在启动过程中需要完成的事情。 |
Images.properties | 提供了图像资源,它被注册在application context XML文件当中。 |
Splash-screen.jpg | 提供了在startup context XML文件中的欢迎窗口图片。 |
Commands-context.xml | 提供了应用程序的命令,组织在菜单栏和工具栏中,以及里面的菜单项。该文件的声明在application context XML中。 |
Messages.properties | 在一个集中的位置提供和展示文本,比如,标题和描述都可以在这里找到。 |
4. 运行程序,你可以看到下面的画面:
Creating a view
现在,我们要在应用程序当中创建一个新的窗口。
a) 右键单击工程,并且选择新建视图:
b) 在新视图对话框中,输入“CustomerView”,并且设置已存在的包作为包名:
c) 单击完成,就生成了一个继承自Spring RCP AbstractView类的新类:
打开richclient-application-context.xml,在文件的最后,注意到你的视图已经被自动注册:
最后,打开ui/message.properties会发现有新的菜单项可以打开这个视图:
CustomerView.label= &CustomerView
d) 运行程序,打开菜单,就可以打开新的Customer视图:
e) 把我们的视图改为在应用程序启动时默认打开。换句话说,Customer视图将会成为应用程序的初始化视图。为了达到目的,首先,打开richclient-application-context.xml并且找到“id”为“lifecycleAdvisor”的bean。增加下面的属性:
< property name ="startingPageId" value ="CustomerView" />
注意名称属性可由代码补全自动完成:
因此,整个bean的定义现在如下:
f) 再次运行程序,就会默认打开Customer视图。
Adding Customer Data
下一步,我们会利用Spring视图来展示用户数据。我们将会使用捆绑在IDE的数据库。
1. 右键单击工程并新建JPanel form,将panel命名为“CustomerPanel”并且选择“Simple”包,单击完成;
2. 打开“CustomerView.java”。改变初始化的JPanel,用CustomerPanel代替:
3. 打开服务窗口(Ctrl-5)。在服务窗口中,展开数据库节点,右键单击jdbc:derby-node,并选择连接。现在,IDE已经连接到了捆绑的数据库。展开jdbc:derby节点,在展开Tables节点,并注意到有一个叫做“Customer”的表,该表就是将在程序里面显示的表。
4. 在设计模式中打开CustomerPanel,然后将一个表格控件从控件面板中拖入到CustomerPanel的视图上,最后再将数据库中的Customer拖放到表格控件上,就会看到下面的窗口:
5. 相关的JAR文件会自动添加到你的工程当中。如果文件没有加入,并且在生成的代码中看到了许多错误信息,那么右键单击库节点,选择添加库,并且添加“Beans Binding”和“TopLink Essentials”,还有从JDK的db/lib文件夹中添加“derbyclient.jar”。
6. 回到项目窗口,可以看到JPA-related已经被加入到项目当中:
7. 运行程序,可以看到相应的数据:
Adding Docking Views
现在,我们只拥有一个视图。开发者们选择RCP的一个主要原因是它的窗口控制系统。一旦桌面应用程序变得负责,你将面临处理多重窗口的问题。除了简单的显示多个窗口,你还需要提供最大化和最小化功能、打开和关闭功能、以及停靠和悬浮功能。Spring RCP可以帮助我们实现这些基本的需求。
1. 首先,我们要添加新的视图,使得我们可以拥有两个窗口。根据前面的教程,使用Spring的视图模板在同一个包里添加一个新的视图。像以前一样,该视图会被注册到richclient-application-context.xml的文件中,同时也被注册到messages.properties文件中。
2. 当运行程序的时候,在窗口|显示视图菜单下面会有两个视图菜单项。通过选择,第二个视图会替代第一个视图显示,反过来也一样。那不是停靠,是替换窗口。我们需要让两个窗口同时显示,即同时停靠显示在主窗口中。
3. 添加下面的bean到richclient-application-context.xml文件中:
< bean id ="applicationPageFactory" depends-on ="serviceLocator"
class="org.springframework.richclient.application.docking.vldocking.VLDockingApplicationPageFactory" >
4. 运行程序,就可以看到下面的结果:
5. 接下来,找到bean当中两个视图的声明,并且将两个类在richclient-application-context.xml文件中使用的类改变如下:
org.springframework.richclient.application.docking.vldocking.VLDockingViewDescriptor
改变后, customer 视图的 bean 应该如下所示(自己创建的视图也同样):
< bean id ="CustomerView" class ="org.springframework.richclient.application.docking.vldocking.VLDockingViewDescriptor" >
< property name ="viewClass" value ="simple.CustomerView"/>
6. 让我们更仔细的看一下定义的视图。找到CustomerView的bean,将光标放置在属性元素“name”的前面,使用快捷键调出代码补全窗口,可以看到其它可能值的列表:
继续将xx-Enabled的属性全部设置为“true”:
根据你想应用的属性功能,你可以对任何视图做相同的事情。上面的属性功能都与字面意思相同,除了“autoHideEnabled”,指的是视图的最小化功能。
7. 再一次运行程序,会发现视图上面多了一些小按钮:
如果你右键点击视图标题栏,会看见一些选项,它们可以通过一些快捷键来触发:
8. 尝试一些程序特性,比如,单击“Detach”按钮,可以将整个视图移出应用程序(如果有多个显示器的话非常有用):
注意: 为了能够拖动移除的视图,必须使光标变成十字的形状,这就需要将光标移至视图标题栏的虚线处。
9. 最后,拖动视图的标题栏,直到能看到阴影的位置释放:
10. 一旦拥有了更多的窗口,你可以移动它们,甚至像标签页一样显示,如果拖动窗口到适当的位置,就会出现下面的图形:
Enable Actions
在菜单栏中,有许多菜单项是默认可用的。所有的菜单栏和工具栏都是在“command-context.xml”文件中声明的。而该文件和其中的内容又是在“richclient-application-context.xml”文件中声明的。
1. 打开richclient-application-context.xml,可以看到command-context.xml文件的声明:
注意: 菜单栏和工具栏也在上面声明,并且会在command-context.xml中更详细的说明。
2. 注意到上面的第三行,也就是command-context.xml文件,让我们一起来看一下帮助菜单:
“帮助内容”的菜单项是无效的,而“关于”菜单项是有效的,下面会解释原因。
3. 查看在command-context.xml中menubar的bean,可以看到成员中有一项是“helpMenu”。按住Ctrl健并单击“helpMenu”的链接,可以直接跳到它的定义:
4. 现在可以看到为什么“帮助内容”是无效的,而“关于”是有效的。第一种情况,它的值只是被声明了;而第二种情况,有一个bean的引用,有一个定义好的类来处理菜单事件。让我们来对“帮助内容”做相同的事情,为它创建一个新的bean。
< bean id ="helpContentsCommand" class ="org.springframework.richclient.command.support.HelpContentsCommand" >
< property name ="helpSetPath" value ="help/simple-hs.xml"/>
注意: “help/simple-hs.xml”是JAVA帮助文件,你需要自己创建它。为了节省时间,可以通过新建工程,在“Sample”项里面随便选择一个Spring Rich Client示例。完成向导,然后拷贝工程的“help”包到自己应用程序的“Resource Packages”下。
5. 最后,我们还需要在help menu中引用bean,如下图所示:
< bean id ="helpMenu"
class ="org.springframework.richclient.command.CommandGroupFactoryBean" >
< property name ="members" >
< list >
< ref bean ="helpContentsCommand" />
< value > separator
< ref bean ="aboutCommand" />
6. 运行程序,就可以看到“帮助内容”菜单项是可用的了。
Adding Context Sensitivity
当你的程序不断扩展时,并不是所有的视图都会用到一些命令,比如每个菜单项不需要对所有窗口有效。在大型程序中,这一部分被称作“context sensitivity”或“selection management”。根据当前的视图或窗口环境,一些功能特性是可用的,而另外的则是被隐藏的或变灰无效的。
因此,在这一部分,我们要设置一个“New”的命令,让它在Customer视图为当前视图的时候才可用。如果当前视图不是Customer视图,“New”菜单项和工具栏按钮都不可用,如下图所示:
反过来,当前视图是Customer视图的时候,菜单项和工具栏都是可用的:
为了实现上面的效果,需要修改CustomerView类,如下所示:
注意到代码中的下面部分:
在这里引用了“newCommand”,它的定义在哪里?如往常一样,所有的命令都在“command-context.xml”文件中定义。在文件中,“newCommand”在“windowCommandManager”bean下面的“sharedCommandIds”进行了声明。在每个视图中,不同的target executor可能被定义为相同的命令。在上面的代码中,在Customer视图中定义了一个“AnctionCommandExecutor”,用来处理显示一个带信息的JOptionpane对话框。在OtherView中,可能有其它处理“newCommand”的方式。换句话说,尽管“newCommand”是全局可见的,但在每个视图中的实现可以是不同的。
有许多预先定义好的命令,可以直接在自己的代码中声明:
对于上面的视图来说,所有声明的命令都是可用的,命令的处理由“GlobalCommandIds”的第二个参数决定。还可以通过在“command-context.xml”文件中声明,在工具栏上增加按钮。
Changing the Look&Feel
由于是标准的Swing应用程序,我们可以改变Look and Feel。打开“richclient-application-context.xml”文件,并且找到下面的bean:
将Look and feel改成Metal:
< bean id ="lookAndFeelConfigurer"
class ="javax.swing.plaf.metal.MetalLookAndFeel" >
运行结果如下图所示: