沉默了近一個月,終于有時間寫Blog了。這些日子除了忙于工作還抽時間看Flex,發現ActionScript的編程思路和SWT、Swing有很多相似之處,而且語法也和Java很相似??傊覍lex極為看好。今后可能要穿插地寫些Flex的Blog了:)
前寫日子看留言,有人說VB、VC的界面設計都是將界面保存成一個資源文件,這樣能完全做到界面與邏輯的分離。我從事UI設計以來,用過像JBuilder、NetBeans的GUI拖拽工具,但是實現方式均是生成Java代碼而已,這樣不但容易造成偶合,而且工具生成的代碼往往冗長。從我的項目經驗來看,UI部分大多數代碼出現在組件的創建與布局這一環節,如果你使用Matisse將組件布局設置成GridBagLayout或GroupLayout,再隨便拖拽兩三個空間上去,觀察下代碼,很長。而且不了解GridBagLayout和GroupLayout的非專業UI設計人員很難讀懂。
“將界面保存成一個資源文件”類似想法早就有了,一直想通過xml配置將組件生成而非hardcoding。下一篇的文章將作詳細介紹。在此之前,先解決一個bug,關于自定義布局類FormLayout和CenterLayout。這兩個布局的preferredLayoutSize方法實現如下:
public Dimension preferredLayoutSize(Container target) {
return target.getPreferredSize();
}
其實是不對的,如果這樣的話當容器沒有設置setPreferredSize的話,運行時會產生堆棧溢出錯誤。解釋下緣由。
java.awt.Container的getPreferredSize方法定義如下
public Dimension getPreferredSize() {
return preferredSize();
}
追蹤到preferredSize:
@Deprecated
public Dimension preferredSize() {
/* Avoid grabbing the lock if a reasonable cached size value
* is available.
*/
Dimension dim = prefSize;
if (dim == null || !(isPreferredSizeSet() || isValid())) {
synchronized (getTreeLock()) {
prefSize = (layoutMgr != null) ?
layoutMgr.preferredLayoutSize(this) :
super.preferredSize();
dim = prefSize;
}
}
if (dim != null){
return new Dimension(dim);
}
else{
return dim;
}
}
發現如果prefSize為空等原因的話,可能返回布局類的layoutMgr.preferredLayoutSize方法。所以說,如果在布局類的preferredLayoutSize實現中返回容器的getPreferredSize,那么很可能陷入函數調用的循環中,最終導致堆棧溢出程序終止。類似的還有minimumLayoutSize和maximumLayoutSize方法,修復的實現如下:
public Dimension preferredLayoutSize(Container target) {
target.getPreferredSize();
synchronized (target.getTreeLock()) {
return new Dimension(0, 0);
}
}
預計周末發表《通過xml配置文件定義及布局組件》