Posted on 2011-10-13 15:28
TWaver 阅读(1552)
评论(0) 编辑 收藏
我们在日常Swing开发过程中,经常会用到JTree组件,且经常会有“动态过滤”的要求。动态过滤的含义是:在一颗巨大的树上面,需要动态的对数据进行过滤。那么,怎么来实现这个要求呢?
听上去动态过滤很简单,实则不然。举一个例子:我们有一个巨大的树结构,层次很深。树中的各个树枝、树叶,都可能会有“问题”产生。假如我们要动态过滤,仅仅显示“所有有问题的数据”,那么,该如何实现呢?不要忘了一点:如果一个树杈自己没问题,但是下面存在有问题的孩子,甚至孙子,它都必须要显示而不能被过滤掉,否则,老爹没有了,孩子何来?正所谓皮之不存,毛将焉附?
仔细思考起来,情况有点复杂了。我们首先想到的是,可以用TWaver的TTree来做树,然后用VisibleFilter进行数据过滤。不过,要判断每一个数据是否要显示,不但要判断自己“有无问题”,还要判断“任何一个孩子或后代有无问题”,一旦有问题,则必须显示,否则则隐藏。
如果要动态的循环便利所有子层孩子,且不说要写大量代码,单单这个重复计算消耗就吃不消。有无简单的方法呢?
突然,这时候,我们想起了TWaver中一个固有功能:告警及告警传播。在TWaver的DataBox中,已经预置了告警传播功能。当DataBox中任何数据发生了告警,则会沿着父对象的路径进行传递,直到最顶层。而每一个对象,其传播的结果,都会在Element.getAlarmState()这个对象中存储,我们可以直接调用查看。看来,我们可以直接利用TWaver的这一特性,避免“重新发明轮子”。
整理思路,可以这样:首先,用TWaver的TTree和DataBox中的告警传播机制,在每一个数据“发生问题”的时候,就创建一个告警。此时,告警会在DataBox中自动传播。然后,在显示的时候,我们给树增加一个过滤器VisibleFilter,判断其是否有告警(这个判断不但判断是否有自身告警,也包括传播告警,也就是被子孙传播上来的告警)。如果有告警,就显示,否则就隐藏。
在作者的应用中,需要显示的是一个产品的产品结构分解,也就是BOM结构,它是一个多层次的结构。当预测到物料可能发生短缺,就会“产生问题
”,具体做法是,给这个数据产生一个“告警”。代码如下:
1//当库存数小于零的时候,则意味着发生物料短缺,此时产生告警。
2if (onhandQuantity.compareTo(BigDecimal.ZERO) < 0) {
3 this.getAlarmState().clear();
4 this.getAlarmState().addNewAlarm(AlarmSeverity.CRITICAL);
5}
显示效果如下:
接下来,我们再给tree设置一个过滤器,判断每一个结点是否有告警(包括被传播告警)。如果有告警,意味着自己或下方有问题存在,显示,否则,就隐藏。
1VisibleFilter visibleFilter = new VisibleFilter() {
2 public boolean isVisible(Element element) {
3 //这里太cool了,直接一句话代替了原来1000多行代码,简单高效!
4 return !element.getAlarmState().isEmpty();
5 }
6};
接下来,在界面上用一个JCheckBox控制visible是否生效,就结束了。
来,看一下过滤后的效果:
效果不错吧,是不是有点四两拨千斤的味道呢?
活学活用,TWaver会给你不断带来意想不到的惊喜。