Dorado 5 : b.主框架界面实现 (T1B)

初级培训教程中实现该例时,是通过配置View中Menu对象的菜单项,通过View的定义初始化菜单。在本章的培训中我们将会利用组件的动态编程技术,通过Java代码动态初始化菜单。动态编程技术同样适用于所有的dorado组件。我们通过该例的学习,借以了解dorado中的组件动态编程技术,在实际使用中灵活运用就是了。本例选用Menu对象说明组件的动态编程技术也是因为其有相当的代表性。在很多应用中的主菜单都是从数据库中读取的。或者说来自于持久层。本例为了说明组件的动态编程技术,将会直接采用Java编程的技术实现菜单的初始化工作,而暂时不与数据库或持久层相关。使得问题简单化,便于学习。实际开发时只要稍作调整就可以满足应用的要求。
Dorado中的各种组件都统一的由视图模型来管理,由视图模型创建和初始化组件,实现组件的动态编程就是定义视图模型实现类,并截取视图模型初始组件相应事件进行编程的过程。视图模型实现类(实现类的说明参考<<dorado 5 用户指南1.1.doc>>)主要提供的事件和方法有:

事件或方法

说明

createControl

在当前视图模型中创建新的组件对象

getControl

获得视图模型中已经定义过的组件对象

initControls

当视图模型初始化自身的组件对象时触发

initControl

也是视图模型初始化自身的组件时触发,由initControls事件负责调用。

下面我们就利用以上提到的几个方法或事件实现主界面菜单对象的动态定义。

新建视图模型

在src的hr目录下新建一个View用来实现主框架页面(命名为Main):

图表 5 3

新建MenuBar

选择controls节点,并添加MenuBar对象,将新增的MenuBar对象的id修改为menubarHr,其他属性设置如下图:

图表 5 4
其中的menu属性保持为空,我们将在后面的实现类中动态的设定该属性。

新建OutlookBar

选择controls节点,并添加OutlookBar对象,设定新增的OutlookBar的属性为outlookbarHr,其他属性设置如下图:

图表 5 5
其中的menu属性保持为空,我们将在后面的实现类中动态的设定该属性。

配置视图模型的实现类

将Main视图切换回Properties Inspector标签设计视图上,并选择View根节点:

图表 5 6
找到左侧的 快捷按钮创建该视图模型的实现类。

图表 5 7
保持磨人的Class Name为MainViewModel以及默认的Package为hr不变,注意给Options列表中的initControls数据行打勾,表示我们要对实现类的initControls事件自定义。单击OK按钮完成向导设计。
系统会自动生成MainViewModel.java,代码如下:

package hr;
import com.bstek.dorado.common.*;
import com.bstek.dorado.data.*;
import com.bstek.dorado.view.*;
import com.bstek.dorado.view.data.*;
import com.bstek.dorado.view.control.*;
/**
 * MainViewModel
 */
public class MainViewModel extends DefaultViewModel {
    protected void initControls() throws Exception {
        super.initControls();
        // Add your code here
    }
}

并将给java类绑定到Main视图模型上,如下图的clazz属性:

图表 5 8
下面我们在实现类的initControls事件中添加menu对象的初始化代码,首先利用createControl方法在super.initControls();代码的下面创建一个Menu对象:

Menu menuHr = (Menu)this.createControl("Menu", "menuHr");

之后我们将创建好的menuHr对象利用其addItem的方法添加内部的菜单项,作初始化工作:

MenuItem item = menuHr.addItem("system", "系统");

其中addItem方法的第一个参数为name,第二个参数为label。该方法返回一个菜单项对象MenuItem。
再利用MenuItem的addItem方法,可以给菜单项下添加子菜单项,例如系统下面再添加一个"我的信息"菜单项:

 MenuItem item = menuHr.addItem("system", "系统"); 
 item.addItem("myInfo", "我的信息");

通过以上的方法最终实现整个菜单的初始化工组,所有的代码如下:

 protected void initControls() throws Exception {
        super.initControls();
        Menu menuHr = (Menu) this.createControl("Menu", "menuHr");
        MenuItem item = menuHr.addItem("system", "系统");
        item.addItem("myInfo", "我的信息");
        item.addItem("changePwd", "修改密码");
        item.addItem("exit", "退出");
        item = menuHr.addItem("manage", "人事");
        item.addItem("branch", "分公司信息");
        item.addItem("dept", "部门信息");
        item.addItem("employee", "员工信息");
        item.addItem("integrate", "综合管理");
        item = menuHr.addItem("report", "报表");
        item.addItem("employee", "员工报表");
    }

这样我们就实现了menuHr的Java代码动态初始化。
下一步,我们将动态创建的menuHr绑定到视图模型中已经存在的menubarHr和outlookbarHr上,我们通过getControl方法获取视图模型中已经定义过的组件对象:

 MenuBar menubarHr = (MenuBar)getControl("menubarHr"); 
 OutlookBar outlokbarHr = (OutlookBar)getControl("outlookbarHr");

并利用MenuBar和OutlookBar的setMenu方法设定其绑定的菜单为menuHr:

 MenuBar menubarHr = (MenuBar)getControl("menubarHr"); 
 menubarHr.setMenu("menuHr"); 
 OutlookBar outlokbarHr = (OutlookBar)getControl("outlookbarHr"); 
 outlokbarHr.setMenu("menuHr");

最终initControls方法的完整代码如下:

 protected void initControls() throws Exception {
        super.initControls();
        Menu menuHr = (Menu) this.createControl("Menu", "menuHr");
        MenuItem item = menuHr.addItem("system", "系统");
        item.addItem("myInfo", "我的信息");
        item.addItem("changePwd", "修改密码");
        item.addItem("exit", "退出");
        item = menuHr.addItem("manage", "人事");
        item.addItem("branch", "分公司信息");
        item.addItem("dept", "部门信息");
        item.addItem("employee", "员工信息");
        item.addItem("integrate", "综合管理");
        item = menuHr.addItem("report", "报表");
        item.addItem("employee", "员工报表");
        MenuBar menubarHr = (MenuBar) getControl("menubarHr");
        menubarHr.setMenu("menuHr");
        OutlookBar outlokbarHr = (OutlookBar) getControl("outlookbarHr");
        outlokbarHr.setMenu("menuHr");
 }

完成了initControls事件的定义之后,下一步开始创建JSP。

创建JSP

到此为置止,主框架的大部分元素都完成了,下一步利用视图模型提供的JSP生成向导自动生成JSP页面。确保在视图模型处在Properties Insppector标签页上:

图表 5 9
并选择Main视图模型的根节点View节点,单击左侧的快捷按钮 ,打开JSP生成向导:

图表 5 10
选择WebRoot目录,单击OK按钮,在hr目录下生成新的JSP页面:

<%@ page contentType="text/html; charset=UTF-8" %> 
<%@ taglib uri="http://www.bstek.com/dorado" prefix="d" %> 
 <html> 
 <head> 
 <title></title> 
 </head> 
 <body> 
 <d:View config="hr.Main"> 
 <d:OutlookBar id="outlookbarHr" /> 
 <d:MenuBar id="menubarHr" /> 
 </d:View> 
 </body> 
 </html>

下面我们利用dorado提供的布局管理器实现页面的快速布局:

图表 5 11
在<d:MenuBar>标签的上方添加空行,并在光标定位在这个空行的时候。双击右侧的X-insert面板中的Layout(Border).并调整OutlookBar与MenuBar的位置:
调整之后代码如下:

<%@ page contentType="text/html; charset=UTF-8" %> 
<%@ taglib uri="http://www.bstek.com/dorado" prefix="d" %> 
 <html> 
 <head> 
 <title></title> 
 </head> 
 <body style="margin: 0; overflow: hidden"> 
 <d:View config="hr.Main"> 
 <d:Layout type="border"> 
 <d:Pane position="top"> 
 <d:MenuBar id="menubarHr" /> 
 </d:Pane> 
 <d:Pane position="left"> 
 <d:OutlookBar id="outlookbarHr" /> 
 </d:Pane> 
 <d:Pane position="center"> 
 <iframe src="welcome.html" id="frameMain" name="frameMain" frameborder="0" 
 style="width: 100%; height: 100%"> 
 </iframe> 
 </d:Pane> 
 </d:Layout> 
 </d:View> 
 </body> 
 </html>

代码中新增了iframe对象frameMain,后面的各个菜单的功能界面将会在frameMain中打开。
<body>标签修改为,使边框为0:

<body style="margin: 0; overflow: hidden">

其中welcome.html为一个欢迎页面,也同样在WebRoot根目录下(可自行创建一个):

<html> 
 <head> 
 <title></title> 
 </head> 
 <body> 
 <table border="0" width="100%" height="100%"> 
 <tr> 
 <td align="center"> 
 <img src="../images/bannerfree.jpg" border="0"> 
 </td> 
 </tr> 
 </table> 
 </body> 
</html>

预览

保存所有的之后,在浏览器中输入(如果还没有启动服务则先选择project菜单项下的start up service):

在登陆界面中的帐号栏位中输入admin登陆之后:

图表 5 12
菜单设计完成。

添加菜单连接功能

现在整个框架元素都显示出来了,可是我们还没有定义单击菜单项时需要跳转的目标URL。
下面我们实现菜单项的的链接功能。
MenuItem拥有一个path属性,该属性用以设定单击该菜单项时要跳转的目标URL。如:

menuItem.setPath("system/myInfo.jsp");

设置了子菜单的path属性后,系统就会利用子菜单的path定义打开新的窗口。
在主框架的JSP页面设计中我们在main.jsp中加入了一个Iframe对象:

<iframe src="welcome.html" id="frameMain" name="frameMain" frameborder="0" 
 style="width: 100%; height: 100%"> 
 </iframe>

如果我们希望新的菜单项打开的页面直接显示在frameMain中,则我们需要设定Menu对象的target属性,该属性表示菜单中的菜单项在target指定的目标区域打开新的URL。initControls事件代码中,在创建Menu对象之后添加代码:

Menu menuHr = (Menu)this.createControl("Menu", "menuHr"); 
menuHr.setTarget("frameMain"); 
MenuItem item = menuHr.addItem("system", "系统"); 
...


为了方便以后的下面组织结构的开发,我们重新修改initControls方法,设置其他相关子菜单的path属性,最终的代码如下:

  protected void initControls() throws Exception {
        super.initControls();
        Menu menuHr = (Menu) this.createControl("Menu", "menuHr");
        menuHr.setTarget("frameMain");
        MenuItem item = menuHr.addItem("system", "系统");
        MenuItem subItem = item.addItem("myInfo", "我的信息");
        subItem.setPath("system/myInfo.jsp");
        subItem = item.addItem("changePwd", "修改密码");
        subItem.setPath("system/changePwd.jsp");
        subItem = item.addItem("exit", "退出");
        subItem.setPath("login.jsp");
        item = menuHr.addItem("manage", "人事");
        subItem = item.addItem("branch", "分公司信息");
        subItem.setPath("manage/branch.jsp");
        subItem = item.addItem("dept", "部门信息");
        subItem.setPath("manage/dept.jsp");
        subItem = item.addItem("employee", "员工信息");
        subItem.setPath("manage/employee.jsp");
        subItem = item.addItem("integrate", "综合管理");
        subItem.setPath("manage/integrate.jsp");
        item = menuHr.addItem("report", "报表");
        subItem = item.addItem("employee", "员工报表");
        subItem.setPath("report/employee.jsp");
        MenuBar menubarHr = (MenuBar) getControl("menubarHr");
        menubarHr.setMenu("menuHr");
        OutlookBar outlokbarHr = (OutlookBar) getControl("outlookbarHr");
        outlokbarHr.setMenu("menuHr");
    }

这样我们就全部完成了主界面的设计以及菜单项动态创建和初始化工作。