我們都知道
java的GUI界面定義是由awt類和swing類來完成的
它在布局管理上面采用了容器和布局管理分離的方案
也就是說
容器只管將其他小件放入其中
而不管這些小件是如何放置的
對於布局的管理交給專門的布局管理器類(LayoutManager)來完成
其實
java在GUI方面應該是並不成功的
Awt類和swing類的結構非常復雜
加上充斥其間的子類繼承和接口實現
使得要想掌握這兩個類非常困難
這也是很多的java程序員抱怨的事情
但GUI已經成了程序發展的方向
所以這裡我們也得勉為其難了
現在我們來看java中布局管理器的具體實現
我們前面說過
java中的容器類(Container)
它們只管加入小件(Meta)
也就是說
它只使用自己的add()方法向自己內部加入小件
同時他記錄這些加入其內部的小件的個數
可以通過container
getComponentCount()方法類獲得小件的數目
通過container
getComponent(i)來獲得相應小件的句柄
然後LayoutManager類就可以通過這些信息來實際布局其中的小件了
java已經為我們提供了幾個常用的布局管理器類
例如
BorderLayout
FlowLayout
GridBagLayout等等
但在實際的布局上
我們還是會有其他的需要
我在不久前的一個問題中曾經要一個垂直的流式布局
我稱之為VflowLayout
其實BoxLayout和GridBagLayout可以完成類似的工作
但前者是swing類的成員
我的客戶端是一個applet
不能使用
而後者必須在類生成的時候指定列數
而失去了靈活性
所以我決定重寫一個自己的布局管理器來實現
經過分析
所有的LayoutManager都要實現一個接口
就是LayoutManager Inerface或者是他的一個子接口LayoutManager
Interface
後者用於復雜的布局管理
例如GridCardLayout
LayoutManager有五個方法需要實現
分別是
public void addLayoutComponent(String name
Component comp);
public void removeLayoutComponent(Component comp);
public Dimension preferredLayoutSize(Container container);
public Dimension minimumLayoutSize(Container container);
public void layoutContainer(Container container);
第一個方法其實就是你在使用container
add(String name
component comp);時調用的方法
例如BorderLayout為布局管理器時
但在FlowLayout中由於沒有其他的附加信息
所以不需要填充這個方法
相應的第二個方法也就不需要填充了
真正核心的方法是第三個和第五個方法
前者是最終確定Container有多大的
而後者就是決定Container中各個小件的實際位置的了
也就是說
當我們用container
setLayout(LayoutManager)後
再加入小件後
最後系統做的工作其實是LayoutManager
layoutContainer(container);和container
setSize(LayoutManager
PreferredLayoutSize(container));
下面是我的新類
VflowLayout
package render_account;
import java
awt
*;
import java
io
*;
public class VFlowLayout implements LayoutManager
Serializable{
int hgap;
int vgap;
public VFlowLayout(){
this(
);
}
public VFlowLayout(int i
int j){
this
hgap=i;
this
vgap=j;
}
public void addLayoutComponent(String name
Component comp){
}
public void removeLayoutComponent(Component comp){
}
public Dimension preferredLayoutSize(Container container){
synchronized(container
getTreeLock()){
Dimension dimension
=new Dimension(
);
int i=container
getComponentCount();
for(int j=
;j Component component = container
getComponent(j);
if(component
isVisible()){
Dimension dimension
=component
getPreferredSize();
dimension
width=Math
max(dimension
width
dimension
width);
if(j>
) dimension
height+=vgap; dimension
height+=dimension
height;
}
}
Insets insets=container
getInsets();
dimension
height+=insets
top+insets
bottom+vgap*
;
dimension
width+=insets
left+insets
right+hgap*
;
Dimension dimension=dimension
;
return dimension;
file://return(new Dimension(
));
}
}
public Dimension minimumLayoutSize(Container container){
synchronized(container
getTreeLock()){
Dimension dimension
=new Dimension(
);
int i=container
getComponentCount();
for(int j=
;j Component component = container
getComponent(j);
if(component
isVisible()){
Dimension dimension
=component
getMinimumSize();
dimension
width=Math
max(dimension
width
dimension
width);
if(j>
)
dimension
height+=vgap;
dimension
height+=dimension
height;
}
}
Insets insets=container
getInsets();
dimension
height+=insets
top+insets
bottom+vgap*
;
dimension
width+=insets
left+insets
right+hgap*
;
Dimension dimension=dimension
;
return dimension;
}
}
public void layoutContainer(Container container){
synchronized(container
getTreeLock()){
Insets insets=container
getInsets();
int vSpace=container
getSize()
height
(insets
top+insets
bottom+vgap*
);
int componentCount=container
getComponentCount();
int left=insets
left+hgap;
int totalHeight=
;
int width=
;
int componentStart=
;
for(int i=
;i Component component=container
getComponent(i);
if(component
isVisible()){
Dimension dimension=component
getPreferredSize();
component
setSize(dimension
width
dimension
height);
if(totalHeight==
|| totalHeight+dimension
height<=vSpace){
if(totalHeight>
)
totalHeight+=vgap;
totalHeight+=dimension
height;
width=Math
max(width
dimension
width);
}else{
moveComponents(container
insets
top+vgap
left
width
componentStart
i);
totalHeight=
;
left+=hgap+width;
width=dimension
width; componentStart=i;
}
}
}
moveComponents(container
insets
top+vgap
left
width
componentStart
componentCount);
}
}
private void moveComponents(Container container
int top
int left
int width
int componentStart
int componentEnd){
synchronized(container
getTreeLock()){
for(int i=componentStart;i Component component=container
getComponent(i);
if(component
isVisible()){ component
setLocation(left
top); top+=component
getPreferredSize()
height+vgap;
}
}
}
}
public void setHgap(int i){
this
hgap=i;
}
public void setVgap(int i){
this
vgap=i;
}
public int getHgap(){
return(this
hgap);
}
public int getVgap(){
return(this
vgap);
}
}
大家可以試一下
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26862.html