我們都知道,java的GUI界面定義是由awt類和swing類來完成的。它在布局管理上面采用了容器和布局管理分離的方案。也就是說,容器只管將其他小件放入其中,而不管這些小件是如何放置的。對于布局的管理交給專門的布局管理器類(LayoutManager)來完成。
其實(shí),java在GUI方面應(yīng)該是并不成功的。Awt類和swing類的結(jié)構(gòu)非常復(fù)雜,加上充斥其間的子類繼承和接口實(shí)現(xiàn),使得要想掌握這兩個(gè)類非常困難。這也是很多的java程序員抱怨的事情,但GUI已經(jīng)成了程序發(fā)展的方向,所以這里我們也得勉為其難了。
現(xiàn)在我們來看java中布局管理器的具體實(shí)現(xiàn)。我們前面說過,java中的容器類(Container),它們只管加入小件(Meta),也就是說,它只使用自己的add()方法向自己內(nèi)部加入小件。同時(shí)他記錄這些加入其內(nèi)部的小件的個(gè)數(shù),可以通過container.getComponentCount()方法類獲得小件的數(shù)目,通過container.getComponent(i)來獲得相應(yīng)小件的句柄。然后LayoutManager類就可以通過這些信息來實(shí)際布局其中的小件了。
java已經(jīng)為我們提供了幾個(gè)常用的布局管理器類,例如:BorderLayout、FlowLayout、GridBagLayout等等。但在實(shí)際的布局上,我們還是會(huì)有其他的需要。我在不久前的一個(gè)問題中曾經(jīng)要一個(gè)垂直的流式布局,我稱之為VflowLayout,其實(shí)BoxLayout和GridBagLayout可以完成類似的工作,但前者是swing類的成員,我的客戶端是一個(gè)applet,不能使用,而后者必須在類生成的時(shí)候指定列數(shù),而失去了靈活性,所以我決定重寫一個(gè)自己的布局管理器來實(shí)現(xiàn)。經(jīng)過分析,所有的LayoutManager都要實(shí)現(xiàn)一個(gè)接口,就是LayoutManager Inerface或者是他的一個(gè)子接口LayoutManager2 Interface,后者用于復(fù)雜的布局管理,例如GridCardLayout。LayoutManager有五個(gè)方法需要實(shí)現(xiàn),分別是:
1、public void addLayoutComponent(String name, Component comp);
2、public void removeLayoutComponent(Component comp);
3、public Dimension preferredLayoutSize(Container container);
4、public Dimension minimumLayoutSize(Container container);
5、public void layoutContainer(Container container);
第一個(gè)方法其實(shí)就是你在使用container.add(String name,component comp);時(shí)調(diào)用的方法,例如BorderLayout為布局管理器時(shí)。但在FlowLayout中由于沒有其他的附加信息,所以不需要填充這個(gè)方法。相應(yīng)的第二個(gè)方法也就不需要填充了。真正核心的方法是第三個(gè)和第五個(gè)方法,前者是最終確定Container有多大的,而后者就是決定Container中各個(gè)小件的實(shí)際位置的了。也就是說,當(dāng)我們用container.setLayout(LayoutManager)后,再加入小件后,最后系統(tǒng)做的工作其實(shí)是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(5,5);
}
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 dimension1=new Dimension(0,0);
int i=container.getComponentCount();
for(int j=0;j Component component = container.getComponent(j);
if(component.isVisible()){
Dimension dimension2=component.getPreferredSize();
dimension1.width=Math.max(dimension1.width,dimension2.width);
if(j>0)
dimension1.height+=vgap;
dimension1.height+=dimension2.height;
}
}
Insets insets=container.getInsets();
dimension1.height+=insets.top+insets.bottom+vgap*2;
dimension1.width+=insets.left+insets.right+hgap*2;
Dimension dimension=dimension1;
return dimension;
file://return(new Dimension(50,200));
}
}
public Dimension minimumLayoutSize(Container container){
synchronized(container.getTreeLock()){
Dimension dimension1=new Dimension(0,0);
int i=container.getComponentCount();
for(int j=0;j Component component = container.getComponent(j);
if(component.isVisible()){
Dimension dimension2=component.getMinimumSize();
dimension1.width=Math.max(dimension1.width,dimension2.width);
if(j>0)
dimension1.height+=vgap;
dimension1.height+=dimension2.height;
}
}
Insets insets=container.getInsets();
dimension1.height+=insets.top+insets.bottom+vgap*2;
dimension1.width+=insets.left+insets.right+hgap*2;
Dimension dimension=dimension1;
return dimension;
}
}
public void layoutContainer(Container container){
synchronized(container.getTreeLock()){
Insets insets=container.getInsets();
int vSpace=container.getSize().height-(insets.top+insets.bottom+vgap*2);
int componentCount=container.getComponentCount();
int left=insets.left+hgap;
int totalHeight=0;
int width=0;
int componentStart=0;
for(int i=0;i Component component=container.getComponent(i);
if(component.isVisible()){
Dimension dimension=component.getPreferredSize();
component.setSize(dimension.width,dimension.height);
if(totalHeight==0 || totalHeight+dimension.height0)
totalHeight+=vgap;
totalHeight+=dimension.height;
width=Math.max(width,dimension.width);
}else{
moveComponents(container,insets.top+vgap,left,width,componentStart,i);
totalHeight=0;
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);
}
}
大家可以試一下?!@more@]
本文名稱:Java布局管理器深入討論(轉(zhuǎn))-創(chuàng)新互聯(lián)
當(dāng)前路徑:http://www.rwnh.cn/article40/epheo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站策劃、電子商務(wù)、虛擬主機(jī)、品牌網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)