分享
 
 
 

Java布局管理器深入讨论

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

我们都知道,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或者是他的一个子接口LayoutManager2 Interface,后者用于复杂的布局管理,例如GridCardLayout。LayoutManager有五个方法需要实现,分别是:

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);

第一个方法其实就是你在使用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(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(j0)

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(j0)

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.height

if(totalHeight0)

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);

}

}

大家可以试一下。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有