自定義布局管理器-CenterLayout
上文自定義布局管理器-FormLayout介紹了FormLayout的參考實現,利用FormLayout,通過指定left、top、
right(可選)、bottom(可選)布局約束可以對組件進行精確定位。然而有些組件在業務上是有固定尺寸的,例如自定義組件之Button介紹的一樣,通過給按鈕指定4種狀態時的圖片,那么組件的最佳尺寸就是圖片的尺寸,因此組件的PreferredSize就可以確定,所以此時只需要組件中心的確定坐標就可以了,實際組件的Location只和其PreferredSize有關。如下圖所示:
這就是CenterLayout的思想。
修改FormData,只需要添加兩個變量即可。
public final class FormData {
public FormAttachment left;
public FormAttachment right;
public FormAttachment top;
public FormAttachment bottom;
public FormAttachment centerX;
public FormAttachment centerY;
}
CenterLayout與FormLayout不同只在于addLayoutComponent、layoutContainer這兩個
方法實現,其他接口方法均相同,所以下面只介紹這兩個方法實現,其他接口方法請
參閱上文自定義布局管理器-FormLayout
在addLayoutComponent方法的開頭,同樣是對布局約束參數constraints合法性進行檢查,這點與FormLayout大致相同。
throw new IllegalArgumentException("constraints can't be null");
} else if (!(constraints instanceof FormData)) {
throw new IllegalArgumentException("constraints must be a " + FormData.class.getName() + " instance");
} else {
synchronized (comp.getTreeLock()) {
FormData formData = (FormData) constraints;
if (formData.centerX == null || formData.centerY == null) {
throw new IllegalArgumentException("centerX FormAttachment and centerY FormAttachment can't be null");
} else if (comp.getPreferredSize() == null) {
throw new RuntimeException("component must have preferred size before be add into parent with CenterLayout");
}
componentConstraints.put(comp, (FormData) constraints);
}
}
對于CenterLayout來說,FormData對象的centerX、centerY必須給出,因為它代表,點的坐標,除此之外組件必須有PreferredSize屬性來指定組件大小。
layoutContainer方法實現也大致相同
public synchronized void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
int w = target.getWidth();
int h = target.getHeight();
Component[] components = target.getComponents();
for (Component comp : components) {
FormData formData = componentConstraints.get(comp);
if (formData != null) {
...
}
}
}
}
上面這步與FormLayout一樣。關鍵在if語句塊內,代碼如下:
FormAttachment centerX = formData.centerX;
FormAttachment centerY = formData.centerY;
int width = component.getPreferredSize().width;
int height = component.getPreferredSize().height;
int x = (int) (centerX.percentage * w) + centerX.offset - width / 2;
int y = (int) (centerY.percentage * h) + centerY.offset - height / 2;
comp.setBounds(x, y, width, height);
獲得centerX、centerY以及最佳尺寸,如上圖所示,不難得出x、y的計算方法。
至此,自定義布局管理器就介紹到這里,這兩個布局類可以解決很多靜態布局需求,所謂靜態布局是指容器內有什么組件是固定的。如果遇到動態界面,例如組件的內容依照用戶級別、插件擴展點等因素決定,也并不是難事,因為了解了布局管理器運行機制以后可很容易地定義適合你需求的布局類。對于靜態布局來說,你可能厭倦了hard coding來布局,你希望這一切由xml這樣的配置搞定,好,下一部分則開始“壓軸戲”——用配置文件解決布局。
posted on 2007-11-29 16:53 sun_java_studio@yahoo.com.cn(電玩) 閱讀(8220) 評論(1) 編輯 收藏 所屬分類: NetBeans 、GUI Design