TWaver - 專注UI技術(shù)

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          我們?cè)谌粘wing開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)用到JTree組件,且經(jīng)常會(huì)有“動(dòng)態(tài)過(guò)濾”的要求。動(dòng)態(tài)過(guò)濾的含義是:在一顆巨大的樹上面,需要?jiǎng)討B(tài)的對(duì)數(shù)據(jù)進(jìn)行過(guò)濾。那么,怎么來(lái)實(shí)現(xiàn)這個(gè)要求呢?

          聽(tīng)上去動(dòng)態(tài)過(guò)濾很簡(jiǎn)單,實(shí)則不然。舉一個(gè)例子:我們有一個(gè)巨大的樹結(jié)構(gòu),層次很深。樹中的各個(gè)樹枝、樹葉,都可能會(huì)有“問(wèn)題”產(chǎn)生。假如我們要?jiǎng)討B(tài)過(guò)濾,僅僅顯示“所有有問(wèn)題的數(shù)據(jù)”,那么,該如何實(shí)現(xiàn)呢?不要忘了一點(diǎn):如果一個(gè)樹杈自己沒(méi)問(wèn)題,但是下面存在有問(wèn)題的孩子,甚至孫子,它都必須要顯示而不能被過(guò)濾掉,否則,老爹沒(méi)有了,孩子何來(lái)?正所謂皮之不存,毛將焉附?

          仔細(xì)思考起來(lái),情況有點(diǎn)復(fù)雜了。我們首先想到的是,可以用TWaver的TTree來(lái)做樹,然后用VisibleFilter進(jìn)行數(shù)據(jù)過(guò)濾。不過(guò),要判斷每一個(gè)數(shù)據(jù)是否要顯示,不但要判斷自己“有無(wú)問(wèn)題”,還要判斷“任何一個(gè)孩子或后代有無(wú)問(wèn)題”,一旦有問(wèn)題,則必須顯示,否則則隱藏。

          如果要?jiǎng)討B(tài)的循環(huán)便利所有子層孩子,且不說(shuō)要寫大量代碼,單單這個(gè)重復(fù)計(jì)算消耗就吃不消。有無(wú)簡(jiǎn)單的方法呢?

          突然,這時(shí)候,我們想起了TWaver中一個(gè)固有功能:告警及告警傳播。在TWaver的DataBox中,已經(jīng)預(yù)置了告警傳播功能。當(dāng)DataBox中任何數(shù)據(jù)發(fā)生了告警,則會(huì)沿著父對(duì)象的路徑進(jìn)行傳遞,直到最頂層。而每一個(gè)對(duì)象,其傳播的結(jié)果,都會(huì)在Element.getAlarmState()這個(gè)對(duì)象中存儲(chǔ),我們可以直接調(diào)用查看。看來(lái),我們可以直接利用TWaver的這一特性,避免“重新發(fā)明輪子”。

          整理思路,可以這樣:首先,用TWaver的TTree和DataBox中的告警傳播機(jī)制,在每一個(gè)數(shù)據(jù)“發(fā)生問(wèn)題”的時(shí)候,就創(chuàng)建一個(gè)告警。此時(shí),告警會(huì)在DataBox中自動(dòng)傳播。然后,在顯示的時(shí)候,我們給樹增加一個(gè)過(guò)濾器VisibleFilter,判斷其是否有告警(這個(gè)判斷不但判斷是否有自身告警,也包括傳播告警,也就是被子孫傳播上來(lái)的告警)。如果有告警,就顯示,否則就隱藏。

          在作者的應(yīng)用中,需要顯示的是一個(gè)產(chǎn)品的產(chǎn)品結(jié)構(gòu)分解,也就是BOM結(jié)構(gòu),它是一個(gè)多層次的結(jié)構(gòu)。當(dāng)預(yù)測(cè)到物料可能發(fā)生短缺,就會(huì)“產(chǎn)生問(wèn)題
          ”,具體做法是,給這個(gè)數(shù)據(jù)產(chǎn)生一個(gè)“告警”。代碼如下:

          1//當(dāng)庫(kù)存數(shù)小于零的時(shí)候,則意味著發(fā)生物料短缺,此時(shí)產(chǎn)生告警。
          2if (onhandQuantity.compareTo(BigDecimal.ZERO) < 0{
          3    this.getAlarmState().clear();
          4    this.getAlarmState().addNewAlarm(AlarmSeverity.CRITICAL);
          5}

           

          顯示效果如下:

          接下來(lái),我們?cè)俳otree設(shè)置一個(gè)過(guò)濾器,判斷每一個(gè)結(jié)點(diǎn)是否有告警(包括被傳播告警)。如果有告警,意味著自己或下方有問(wèn)題存在,顯示,否則,就隱藏。

          1VisibleFilter visibleFilter = new VisibleFilter() {
          2    public boolean isVisible(Element element) {
          3        //這里太cool了,直接一句話代替了原來(lái)1000多行代碼,簡(jiǎn)單高效!
          4        return !element.getAlarmState().isEmpty();
          5    }

          6}
          ;

          接下來(lái),在界面上用一個(gè)JCheckBox控制visible是否生效,就結(jié)束了。

          來(lái),看一下過(guò)濾后的效果:




          效果不錯(cuò)吧,是不是有點(diǎn)四兩撥千斤的味道呢?

          活學(xué)活用,TWaver會(huì)給你不斷帶來(lái)意想不到的驚喜。



          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 罗源县| 双江| 应用必备| 新沂市| 越西县| 耒阳市| 永兴县| 中江县| 鸡西市| 吉安县| 贺州市| 城口县| 嘉义市| 金沙县| 凭祥市| 偃师市| 郑州市| 常德市| 平阳县| 永清县| 镇原县| 晴隆县| 宝丰县| 明星| 华宁县| 芜湖县| 多伦县| 德昌县| 馆陶县| 府谷县| 洪湖市| 正宁县| 长岭县| 新化县| 曲松县| 徐州市| 南康市| 霍邱县| 寿宁县| 梁山县| 谷城县|