假设这样一种情况,我们的系统的界面使用javax.swing包构建,界面的基础是BaseView,他是一个容器,当然他应当提供获取控件元素的功能,比如得到按钮,下拉框,表格等,当然仅仅是一个容器而已,而我们的界面的元素全部部署在JPanel上。
描述为:
一个界面就是一个BaseView,他只包含一个JPanel,这个包含JPanel包含所有我们的Swing控件,例如JButton,JLable等等。
问题出现了:我们通常因为业务的需要完成一个界面的操作要自动跳转到下一个界面,完成下一个界面又能跳回来(题外话:由于我们的操作是基于GUI的,所 以往往能保存Session信息,而Web却做不到),而这往往成为系统实现过程中效率低下的一个因素,我就见到我现在的系统中有人用600行代码判断上 一个界面应该是哪一个来跳转过来,因为很多界面都可以跳到当前界面。
当然有一种做法是,在下一个界面类中包含指向上一个界面的变量,我们说,这不方便,也增加了依赖性,这对软件是不利的。
接下来,我给出我的解决方法,希望对采用这种界面结构的朋友有所裨益。
(以下全部用简化模型来讲述.)
1.简单点,我们假设BaseView继承JWindow,当然可以是别的容器(依据你的实现),大概象这样:
public abstract class BaseView extends JWindow{ … (实现一些取得界面控件,和界面信息的方法). } |
2.每个界面类都象这样定义:
public class MyView extends BaseView{ JPanel myPanel; public void playoutPanel(){ JButton myButton = new JButton(“OK”); myPanel.add(myButton); …… (添加你需要的控件和布局到myPanel上) } } |
3.假设有其他的界面OneView,TwoView,ThreeView处理完操作后都需要跳转到myView,在myView中的ok按钮按下的时候需要回到原始界面。
原来臃肿的代码需要在myView中添加一个变量BaseView anyView;用来存放转来的那个界面anyView,赋值在三者中的跳转代码中引用myView来设定.跳转代码象这样:
public void jump(){ MyView myView = new MyView(); myView.anyView = this; this.remove(this.xxPanel); this.add(myView.getPanel()); this.repaint(); } |
看起来还不错,虽然需要引用MyView类,并调用他的变量和方法.但是跳转回来却不那么容易,否则怎么会用600行!
大概象这样:(这已经是被我简化的)
public void goBack(){ if(anyView instanceof OneView){ anyView.remove(this.myView); OneView ov = (OneView)anyView; anyView.add(ov.getPanel()); anyView.repaint(); } if(anyView instanceof TwoView){ …. } … } |
不经大量应用别的业务用例界面,这种编译依赖性真不是什么好事,更何况用了大量的低效的instanceof判断和转型操作.
为了优化这种情形,彻底解决这个问题,我想应该设计一个第三方类来消除这种依赖性,并且让界面跳转不要这么费劲。这个第三方的类是这样设计的:
在这个类中,必须有一个变量来保存某一个界面跳转的路径,如A->B->C.路径一旦被保存,你就拥有了控制显示任何一个界面的权利了。在 这个链中,第一个位置的界面应该是这次跳转的第一站,最后一个位置是当前站。这里存在一个因果关系:只有跳转了才可以跳回去。这样使得我们可以用数组来保 存这个路径。现实中,跳转的情形应该不会超过10次,所以我们把路径长度设为10(当然你可以根据需要更改)。这个类的样子大概象这样:
class ViewPath{ JPanel[] pnlPath = null; //跳转的界面路径,界面跳转最大10个层次吧!!! int index = 0; //路径中的当前下标 BaseView bsView = null; //当前路径所在的同一个View //在路径中寻找目标的方法 //构造函数 bsView = myView; //设置该路径所属的那个View |
这样一个类就完成了保存一次跳转路径的作用.(当然,是否应该在find方法中设立目标位置是否合适有待商榷)
那么我们如何使用这样一个路径?
我们设立一个辅助类来完成这个工作,我们命名为ViewJump,我们知道作为辅助的类最好是不要有实例,特别是象这样的起接口作用的类,只提供静态方法.它的框架象这样:
public class ViewJump{ private static ViewPath[] viewPath = null; //路径池,系统多处使用,静态但私有,因为供内部用 private ViewJump(){} //私有构造方法,辅助类只提供静态方法 |
完成这样一个类的代码量并不多,一百多行,但是却使得用户完全脱离了处理不同界面的烦恼.稍后会把该类的源码附上,值得一提的是,这个类的实现固然可以 用到类似的实现当中,但是如果用户的界面结构并不是如此搭建,你就需要更改参数类型了.如果能把这些抽象出来,得到一个抽象类或接口,参数用Object 类型.用户根据自己的需要去实现这些方法,岂不妙哉!
使用这个类,你可以简便的多的完成诸如上面的任务:
OneView中:
public void jump(){ MyView myView = new MyView(); int id = ViewJump.registerPath(this.xxPanel,this); ViewJump.setNext(id,myView.getPanel()); ViewJump.jump(id); } |
MyView中退回的部分:
protected void goBack(){ int id = ViewJump.registerPath(this.myPanel,this); ViewJump.back(id); } |
天哪,这并不神奇,600行代码仅仅用了两行就实现了!
好了,我就说这么多了,一切都掌握在你手中,用你的智慧来优化我们的冗余代码吧,因为这样它看起来相当不错.
附:完整代码:(我把ViewPath类放在同一个文件ViewJump.java里,代码上面已经给出)
public class ViewJump{ private static ViewPath[] viewPath = null; //私有构造函数 //寻找该Panel是不是在路径中 //建立一个新的路径 ViewPath[] vjArr = new ViewPath[viewPath.length]; //获得实例的方法 //设定要跳转的下一个目标 //回到上一个 vp.bsView.validate(); //回到起源处 vp.bsView.validate(); //跳转到下一处 vp.bsView.remove(vp.pnlPath[vp.index]); //移去当前的 |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-131004/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-131004/