现有的布局管理器能不能实现如下布局:****************************************
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
****************************************中间panel固定大小位置,两边panel自动适应
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
****************************************中间panel固定大小位置,两边panel自动适应
package clienttools;import java.util.HashMap;
import java.util.Iterator;import java.awt.*;
import javax.swing.*;/**
* <p>Title: 横向或竖向布置组件</p>
* <p>Description:
* 通过引入该组件来实现在同一个方向布置多个自适应的组件,及固定宽度的组件
* </p>
*/public class NullRatePanel extends JPanel{
//定义排列类型
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1; //存放组件的设置比例
protected HashMap hash = new HashMap();
//默认当前面板的布列方式为横向
protected int lay = HORIZONTAL; public NullRatePanel(int lay) {
this.setLayout(null);
this.lay = lay;
} public NullRatePanel(int lay,Container container) {
this(lay);
if(container != null)
container.add(this);
} //添加组件的唯一方法,按比例分配大小的组件
public void addComp(Component comp,double rate){
Rate r = getRate(comp);
r.isAccRate = true;
r.rate = rate;
} //添加组件的唯一方法,固定大小的组件
public void addComp(Component comp,int size){
Rate r = getRate(comp);
r.isAccRate = false;
r.size = size;
} //覆盖父类的该方法,以布局所有控件
public void setBounds(int x,int y,int width,int height){
//覆盖父类方法
super.setBounds(x,y,width,height);
//如果没有组件
if(this.getComponentCount()<=0)
return; //比例规一化
double ratesum = 0;
Component[] comps = this.getComponents();
for(int i=0;i<comps.length;i++){
Rate rate = getRate(comps[i]);
if(rate.isAccRate)
ratesum += rate.rate;
} //求得按比例排列的总大小
int size = lay == HORIZONTAL ? width : height;
for (int i = 0; i < comps.length - 1; i++) {
Rate rate = getRate(comps[i]);
if (!rate.isAccRate)
size -= rate.size;
} //如果没有设置比例的组件,直接退出
if (ratesum <= 0 || size<=0) {
System.out.println("NullRatePanel中没有设置组件的大小比例,无法排列组件...");
return;
} int cx = 0;
int cy = 0;
int cw = 0;
int ch = 0; if (lay == HORIZONTAL) {
ch = height;
for (int i = 0; i < comps.length-1; i++) {
Rate rate = getRate(comps[i]);
if(rate.isAccRate)
cw = (int)(size * (rate.rate/ratesum));
else
cw = rate.size;
comps[i].setBounds(cx,cy,cw,ch);
cx += cw;
} Component comp = comps[comps.length-1];
cw = width - cx;
comp.setBounds(cx,cy,cw,ch);
}
else{
cw = width;
for (int i = 0; i < comps.length-1; i++) {
Rate rate = getRate(comps[i]);
if(rate.isAccRate)
ch = (int)(size * (rate.rate/ratesum));
else
ch = rate.size;
comps[i].setBounds(cx,cy,cw,ch);
cy += ch;
} Component comp = comps[comps.length-1];
ch = height - cy;
comp.setBounds(cx,cy,cw,ch);
}
} private Rate getRate(Component comp){
if(!hash.containsKey(comp)){
this.add(comp); Rate result = new Rate();
hash.put(comp,result);
} return (Rate)hash.get(comp);
} public void remove(Component comp){
super.remove(comp);
hash.remove(comp);
} /***/
class Rate{
private double rate = 0;
private boolean isAccRate = true; private int size = 0;
} /**
* 测试主函数
* @param args
*/
public static void main(String[] args) {
JDialog dlg = new JDialog(new Frame(), "test");
Container container = dlg.getContentPane();
NullLayout layout = new NullLayout();
container.setLayout(layout); NullRatePanel rateP = new NullRatePanel(NullRatePanel.HORIZONTAL,container); Label label = new Label("Left Label");
rateP.addComp(label,0.5);
label.setBackground(Color.red); Button btn = new Button("Test JButton");
rateP.addComp(btn,100); label = new Label("Right Label");
rateP.addComp(label,0.5);
label.setBackground(Color.red); int x=500;
int y=300;
dlg.setSize(x, y);
dlg.setVisible(true);
rateP.setBounds(0,0,x,y);
}
}
NullLayout layout = new NullLayout();
container.setLayout(layout);
//这两句去掉,这是我自己改进的Null布局管理器,在这里没用上
//原来第76行为 for (int i = 0; i < comps.length - 1; i++){
Rate rate = getRate(comps[i]);
if (!rate.isAccRate)
size -= rate.size;
} 这是我的珍藏代码,想想共享算了,如果谁发现什么错误或者有所改进,别忘了告诉我一声,谢谢
GridBagLayout,中间的部分会改变。谢谢shengli_liao,还是自己实现布局管理器方便些,。回头结贴
=====================================================
GridBagLayout 中间的设置不可横向扩展 两边的设置成true 这样两边会自适应 中间固定不变