最近想要在 UI component 出現 / 消失的時候自動做一些事情,於是打算從 GXT Component
下手。不過怎麼寫怎麼有問題,只好寫 n 個 SSCCE 來確認一下,實驗結果紀錄於此。
基本認識
我關心這四個 method:
onLoad()
onUnload()
onShow()
onHide()
onLoad()
跟 onUnload()
是從 GWT 的 Widget
就定義的 method。理論上跟 onAttach()
、onDetach()
等意,就是這個 component 加入到 DOM(或是從 DOM 中移除)時會觸發的 method。不過 API 都強烈建議用 onLoad()
跟 onUnload()
了,就乖乖照辦。
onShow()
、onHide()
是 GXT Component 開始定義的 method,最常遇到的 caller 大概是 GXT Component 的 setVisible()
(override UIObject
)。
測試環境
- JDK 1.7
- GWT 2.7
- GXT 3.1.0
- Windows 7 (64bit)
- Chrome 50
測試方式
我製造了兩個 component FooButton
(繼承 TextButton
) 跟 FooCP
(繼承 ContentPanel
)。分別 override 上述四個 method,例如:
@Override
protected void onLoad() {
super.onLoad();
Console.log("load " + getText());
}
會需要 FooCP
是因為 AccordionLayoutContainer
跟 BorderLayoutContainer
(在某些情況下)要求 child 是 ContentPanel
。
基本上我是用 UiBinder 撰寫 TestLayout
(btw… TestLayout
繼承的是 GXT 的 Composite
),然後 entry point 的 onModuleLoad()
這樣寫:
Viewport vp = new Viewport();
vp.add(new TestLayout());
RootPanel.get().add(vp);
主要就是測試 FooButton
跟 FooCP
作為各 layout container 還有 GXT TabPanel
(見一次 murmur 一次,為啥這東西不是 container… ==”)的 child 時,上述四個 method 是否會觸發。
component 的行為(例如 collapse、close tab…)都是實際 UI 操作而不是程式呼叫 method。(希望這個差異不會炸出什麼新的問題)。
測試結果
注意:沒有測試所有已知的 layout container。
毫無反應區
下列 container 只會觸發 onLoad()
,不會觸發 onShow()
:
- AccordionLayoutContainer
- CenterLayoutContainer
- ContentPanel
- FieldLabel
- FieldSet(有設定
collapsible=true
) - FlowLayout
- HBoxLayoutContainer
- HorizontalLayoutContainer
- NorthSouthContainer
- SimpleContainer
- VBoxLayoutContainer
- VerticallayoutContainer
BorderLayoutContainer
center 的 child 只會在初始時觸發一次 onLoad()
,其餘操作均無反應。
其他四個 region 在初始時會先依序觸發 onLoad()
,然後再依序觸發 onShow()
… 三次(如果不是用 UiBinder,而是用 Swing 的方式直接掛一個組好的 BorderLayoutContainer
到 Viewport
,就會變兩次….. WTF?)
當某個 region 被 collapse 時,該 component 會觸發 onUnload()
、但是不會觸發 onHide()
。接著,其他還顯示的 region 會依序觸發 onShow()
。
當某個已經 collapse 的 region 展開回原狀時,會先觸發它的 onLoad()
,然後再依序呼叫全部 region 的 onShow()
。
當某個已經 collapse 的 region 以 float 的方式出現 / 消失時,會觸發 onLoad()
/ onHide()
,但是不會觸發其他 region 的 method。
當某個已經 collapse 的 region 以 float 的方式出現,然後再按下展開回原狀的按鈕,看起來是:
- 做 float region 消失的程序
- 做 region 恢復的程序
感覺有優化的空間
CardLayout
一開始會觸發所有 child 的 onHide()
,然後才觸發 onLoad()
,最後才是觸發 active widget 的 onShow()
。
切換 active widget 時,就是觸發對應 child 的 onShow
、onHide
。
TabPanel
(再 murmur 一次,為啥這玩意不是 layout container ==”)
初始時的觸發順序
- active widget 的
onHide()
- active widget 的
onShow()
- 其他 child 的
onHide()
- 全部 child 的
onLoad()
以下假設目前的 active widget 是 Foo1
,另外還有一個 Foo2
。
- 將 active widget 切換為
Foo2
:- 觸發
Foo1
的onHide()
- 觸發
Foo2
的onShow()
- 觸發
- 關掉有
Foo2
的 tab:- 觸發
Foo2
的onUnload()
- 觸發
Foo2
的onShow()
- 觸發
- 關掉有
Foo1
的 tab:- 觸發
Foo1
的onUnload()
- 觸發
Foo1
的onShow()
- 觸發
Foo2
的onShow()
- 觸發
簡單地說,被關掉的 child 都會先觸發 onUnload()
然後再觸發 onShow()
(WTF?)
結論(X) 詰譙(O)
其實不知道要有什麼結論… Orz
AccordionLayoutContainer
跟 FieldSet
並不會觸發 onShow()
/ onHide()
,這點還可以接受。
CardLayoutContainer
的初始化步驟非常怪,都還沒掛上 DOM 那觸發 onHide()
是要幹麼?但是初始化只有一次,所以就算了。
BorderLayoutContainer
的 collapse 行為跟 onHide()
一點關係也沒有,但是會觸發其他 region 的 onShow()
?
TabPanel
可能是集各種詭異於一身的… 對,他還不是 container(謎之聲:你是要講幾次?)。關掉一個 tab 會觸發 onUnload()
這完全合情合理,但是為什麼還會再觸發 onShow()
阿阿阿阿…… Orz
我很願意相信,這背後都有好理由來支撐這一堆詭異行為;只是我更希望能有統一的行為模式,雖然會關心到這種 detail 程度的時候好像不多…
可是我就需要阿... [淚目]
這看起來要 trace javascript code 才能看到全貌
回覆刪除不用耶... 因為基本上都已經包成 Java 的樣子了
回覆刪除Much as they do with numbers in roulette, the betting right here is focused on guessing an outcome. Both the player and the banker are dealt two playing cards face up. If either 온라인카지노 the player or banker has a hand totaling eight or nine, it’s called a natural win. The hand ends and the gamers who bet on the best facet get paid even cash.
回覆刪除