服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

在swing中使用高级的mvc和pojos


  摘要:
  
  tikeswing 是一个开放源码的swing框架,它提供了一个高度mvc(模型-视图-控制器)模式的体系结构并且使swing组件的使用非常简单。它通过将视图组件和javabeans直接连接来支持pojo编程模式。在这篇文章中将阐述tikeswing的特点,并且将示范怎样使用这个框架创建一个清晰的mvc的系结构。(2,400个英文单词;2005年6月20日)
  
  最近,在java社区里面,丰富的互联网应用程序(rias)的兴起成为一个热点话题。另外一些新的技术,像ajax(异步的javascript和xml),macromedia flex, 和laszlo,以及与java web start一起使用的虽旧而好的swing,它们都被提议作为ria技术。
  
  然而,java社区里面的很多人对java基础类库(jfc)和swing提出了批评。swing在建立高度mvc模式的客户端体系方面不能提供太多的帮助。任何合理的服务器应用程序返回传递的对象,或者称为简单初始java对象(pojos),把它传递到客户端的技术证明了j2ee世界的窘境。从pojo范围映射到swing组件需要太多的手动的代码,反之亦然。
  
  同样的,实现swing其他的功能,就像线程句柄和验证域,也是很费力的事情。而且有时候swing组件很难使用:创建一个合适的表格或者树模型通常需要很多的编码,而且需要深入的研究swing编程文档中的api。
  
  tikeswing 是一个开放源码的swing框架,它提供了一个高度mvc(模型-视图-控制器)模式的体系结构并且实现了模型,组件和控制器通信的自动化。它简化了swing组件的使用,并通过将视图组件和javabeans直接连接来支持pojo编程模式。
  
  这篇文章将示范怎样使用tikeswing创建一个清晰的mvc的体系结构。也将阐述建立tikeswing组件的原则,并简单描述在这个框架中包含的最佳体验和机制。
  
  mvc体系结构
  
  众所周知,mvc范例是推荐的图形用户界面发展的基本体系。它还有很多的可用的变种,就像mvc++, hmvc (hierarchical mvc), mvc model 2, mvc push, and mvc pull,它们每一个都有些不同之处。tikeswing基于下面的mvc原则:
  
  ●model 模型:
  
  o来自一些真实世界或者系统的抽象
  
  o包装其数据和函数
  
  o在数据改变时通知观察者 (编者注:observer, 设计模式术语)
  
  ●view 视图:
  
  o系统的用户界面
  
  o依附于模型并通过显示界面将它的内容显示出来
  
  o在模型改变时自动刷新受到影响的部分
  
  ●controller 控制器:
  
  o控制应用程序的流程
  
  o接受用户的输入,并根据用户输入指导模型和视图完成任务
  
  下面的图表表示了tikeswing中mvc的类结构。
  
在swing中使用高级的mvc和pojos

  
图 1. 一个使用tikeswing的应用的mvc类图

  
  类mymodel, myview, 和mycontroller由一个使用框架的应用来实现。mymodel和mycontroller扩展了tikeswing的ymodel 和ycontroller类。一个视图的类可以是任何实现了yicomponent接口的java.awt.component。
  
  tikeswing在装配类结构的时候不使用任何的配置文件。当ycontroller,ymodel和视图组件提供了要求的功能特性的时候,扩展适当的类已经足够了。下面讲述如何使用tikeswing来实现模型、视图和控制器类。
  
  模型
  
  tikeswing的模型是一个为实现视图而包含数据的javabeans组件。一个模型类可能包含嵌套的javabeans,数组,映射和集合。和标准javabeans中要求的一样,所有模型的类变量必须有适当的get和set方法。从这种意义上说,tikeswing就像很多的网络应用程序框架那样工作,所以在不同的技术之间重用模型类是很容易的。
  
  ymodel是模型的基类。它提供了报告数据改变的方法。当触发了一个事件的时候,框架会更新与之相连的视图。在分布式环境中,一个模型类有从服务器应用程序中得到pojos的方法(通常是从隐藏了业务服务的实现细节的业务代理中)。模型自身存储了pojos,且它有责任通知观察者。在有些mvc的体系结构中,一个控制器类和服务器通信,pojos存储在控制器中。然而,tikeswing分离出ymodel类的方法有下面的优势:控制器专著于流程,另外的方法(操作模型数据的)可以被加在客户端。ymodel遵循了传统的mvc模式,所以mvc中类的责任就清晰地分开了。
  
  下面的代码演示了模型类如何通过给定的参数找到customers。模型的类变量name和id是搜索标准,customers是包含搜索结果的customer pojos的集合。findcustomers()方法通过customerservicedelegate从服务器应用程序中得到customers。当方法notifyobservers()激活时,框架会自动更新相连的视图。
  
  public class findcustomermodel extends ymodel {
  private string name;  private string id;
  private collection customers;
  private customerservicedelegate delegate = new customerservicedelegate();
  public void findcustomers() {
  setcustomers(delegate.findcustomers(id, name));
  notifyobservers("customers");
  }  public void setcustomers(collection customers) {
  this.customers = customers;
  }
  public collection getcustomers() {
  return customers;
  }
  public void setid(string id) {
  this.id = id;
  }  public string getid() {
  return id;
  }  public void setname(string name) {
  this.name = name;
  }
  public string getname() {
  return name;
  }}
  
  视图
  
  tikeswing视图是包含其他swing组件的swing组件。通常,一个视图类是一个面板,一个对话框,或者一个帧,它们建立了子组件并将之添加到自身(就像在通常的swing开发环境中一样)。然而,tikeswing应用程序中使用的所有组件都必须实现适当的接口以连接框架的mvc体系结构。幸运的是,框架包含一个很大的为了这种目的已经实现的组件的集合。
  
  一个特殊的名字必须赋予一个视图组件,这样框架就能在组件和被命名的模型类变量之间复制数据。命名的惯例和其他的用于网络应用程序框架的和apache beanutils库(它通常用于框架的执行)类似。下面是支持的命名格式:
  
  ●简单的: 直接连接到模型域的组件;例如,field1
  
  ●嵌套的:连接到模型内部的javabeans域的组件;例如,field1.field2
  
  ●索引的:连接到模型内的数组域的组件;例如myarray[1]
  
  ●映射的:连接到模型内的映射域组件;例如,myhashmap(“foo”)
  
  ●组合的:通过结合符号连接到模型的内部域的组件;例如,field.myarray[1].myhashmap["foo"]
  
  除了模型类的get和set方法外,视图类必须为每一个视图组件建立一个get方法。
  
  下面的例子是为findcustomermodel建立的视图类。它使用了扩展了基础swing类的tikeswing组件(从jlabel到ylabel,jtextfield到ytextfield,等)。例子的代码和标准的swing视图很像,只有setmvcnames()方法包含了tikeswing特有的代码。依照上面讲述的原则,它设定了模型组件的连接。resulttable列通过ycolumn对象与customers集合中的pojo域相连。findbutton不显示任何从模型得到的数据,但是mvc的名字是为tikeswing的事件句柄设定的(以后再讲)。
  
  public class findcustomerview extends ypanel {
  private ylabel idlabel = new ylabel("id");
  private ylabel namelabel = new ylabel ("name");
  private ytextfield idfield = new ytextfield();
  private ytextfield namefield = new ytextfield();
  private ypanel criteriapanel = new ypanel();
  private ytable resulttable = new ytable();
  private ybutton findbutton = new ybutton("find");
  public findcustomerview () {
  addcomponents();
  setmvcnames();
  }
  private void setmvcnames() {
  idfield.getyproperty().put(yicomponent.mvc_name,"id");
  namefield.getyproperty().put(yicomponent.mvc_name,"name");
  resulttable.getyproperty().put(yicomponent.mvc_name,"customers");
  findbutton.getyproperty().put(yicomponent.mvc_name,"findbutton");
  ycolumn[] columns = {        new ycolumn("id"),
  new ycolumn("name")};
  resulttable.setcolumns(columns);
  }    private void addcomponents() {
  this.setlayout(new borderlayout());
  this.add(criteriapanel, borderlayout.north);
  idfield.setpreferredsize(new dimension(100, 19));
  namefield.setpreferredsize(new dimension(100, 19));
  criteriapanel.add(idlabel);
  criteriapanel.add(idfield);
  criteriapanel.add(namelabel);
  criteriapanel.add(namefield);
  criteriapanel.add(findbutton);
  this.add(resulttable, borderlayout.center);
  }
  public ytextfield getidfield() {
  return idfield;  }
  public ylabel getidlabel() {
  return idlabel;
  }
  public ytextfield getnamefield() {
  return namefield;
  }
  public ylabel getnamelabel() {
  return namelabel;
  }
  public ytable getresulttabl

扫描关注微信公众号