Posted on 2011-10-13 15:28
TWaver 閱讀(1562)
評論(0) 編輯 收藏
我們在日常Swing開發過程中,經常會用到JTree組件,且經常會有“動態過濾”的要求。動態過濾的含義是:在一顆巨大的樹上面,需要動態的對數據進行過濾。那么,怎么來實現這個要求呢?
聽上去動態過濾很簡單,實則不然。舉一個例子:我們有一個巨大的樹結構,層次很深。樹中的各個樹枝、樹葉,都可能會有“問題”產生。假如我們要動態過濾,僅僅顯示“所有有問題的數據”,那么,該如何實現呢?不要忘了一點:如果一個樹杈自己沒問題,但是下面存在有問題的孩子,甚至孫子,它都必須要顯示而不能被過濾掉,否則,老爹沒有了,孩子何來?正所謂皮之不存,毛將焉附?
仔細思考起來,情況有點復雜了。我們首先想到的是,可以用TWaver的TTree來做樹,然后用VisibleFilter進行數據過濾。不過,要判斷每一個數據是否要顯示,不但要判斷自己“有無問題”,還要判斷“任何一個孩子或后代有無問題”,一旦有問題,則必須顯示,否則則隱藏。
如果要動態的循環便利所有子層孩子,且不說要寫大量代碼,單單這個重復計算消耗就吃不消。有無簡單的方法呢?
突然,這時候,我們想起了TWaver中一個固有功能:告警及告警傳播。在TWaver的DataBox中,已經預置了告警傳播功能。當DataBox中任何數據發生了告警,則會沿著父對象的路徑進行傳遞,直到最頂層。而每一個對象,其傳播的結果,都會在Element.getAlarmState()這個對象中存儲,我們可以直接調用查看。看來,我們可以直接利用TWaver的這一特性,避免“重新發明輪子”。
整理思路,可以這樣:首先,用TWaver的TTree和DataBox中的告警傳播機制,在每一個數據“發生問題”的時候,就創建一個告警。此時,告警會在DataBox中自動傳播。然后,在顯示的時候,我們給樹增加一個過濾器VisibleFilter,判斷其是否有告警(這個判斷不但判斷是否有自身告警,也包括傳播告警,也就是被子孫傳播上來的告警)。如果有告警,就顯示,否則就隱藏。
在作者的應用中,需要顯示的是一個產品的產品結構分解,也就是BOM結構,它是一個多層次的結構。當預測到物料可能發生短缺,就會“產生問題
”,具體做法是,給這個數據產生一個“告警”。代碼如下:
1
//當庫存數小于零的時候,則意味著發生物料短缺,此時產生告警。
2
if (onhandQuantity.compareTo(BigDecimal.ZERO) < 0)
{
3
this.getAlarmState().clear();
4
this.getAlarmState().addNewAlarm(AlarmSeverity.CRITICAL);
5
}
顯示效果如下:

接下來,我們再給tree設置一個過濾器,判斷每一個結點是否有告警(包括被傳播告警)。如果有告警,意味著自己或下方有問題存在,顯示,否則,就隱藏。
1
VisibleFilter visibleFilter = new VisibleFilter()
{
2
public boolean isVisible(Element element)
{
3
//這里太cool了,直接一句話代替了原來1000多行代碼,簡單高效!
4
return !element.getAlarmState().isEmpty();
5
}
6
};
接下來,在界面上用一個JCheckBox控制visible是否生效,就結束了。
來,看一下過濾后的效果:

效果不錯吧,是不是有點四兩撥千斤的味道呢?
活學活用,TWaver會給你不斷帶來意想不到的驚喜。