TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
这个布局管理器和空布局管理器类似,也是用绝对坐标调位置的,可以完全兼容NULL布局管理器,不过对它进行了一些改进,实现了以下功能:
1.可以随框架大小的改变而改变组件的位置和大小。
2.可以指定当前组件的大小与以前组件具有相同的大小,这样当要添加多个大小相同的组件时即可以只设置一个组件的大小,在添加其它组件时只用add(cmp,oldCmp);即可实现,代码如下。 /*ComponentStruct.java*/ import java.util.*;
import java.awt.*;
final class ComponentStruct{
int counts; //表示容器中组件的个数
Component comp; //保存组件
Rectangle oldRect; //保存组件的坐标和大小
public ComponentStruct(){
this(0,null,null);
}
public ComponentStruct(int counts , Component comp , Rectangle oldRect){
this.counts = counts;
this.comp = comp;
this.oldRect = oldRect;
}
}
/**FreedomLayout.java
*自己定制的一种布局管理器,实现了以下的功能:
*1.能够像空布局管理器那样用绝对数值来调位置和大小
*2.具有像普通管理器那样组件能够随框架的改变而改变
*3.可以让某组件与指定位置(Z顺序)或名称的组件的大小相同,若忘记了组件名,还可以用FIRST,和PREVIOUS属性与第一个或上一个组件的大小相同
*/
import java.awt.*;
import java.util.*;
class FreedomLayout implements LayoutManager2{
private int counts=0;//统计框架中添加组件的个数
private Vector<ComponentStruct> components = new Vector<ComponentStruct>();//框架中所添加的组件的数据结构
Rectangle newRect= null; //保存最新框架的坐标和大小
Rectangle oldRect= null; //保存最初框架的坐标和大小
public static final String FIRST="first";//表示第一个组件.
public static final String PREVIOUS="previous";//表示上一个组件。
//private static final Dimension SCREENSIZE = Toolkit.getDefaultToolkit().getScreenSize();//获取屏幕尺寸
//private static final Dimension REMAINSIZE = new Dimension(SCREENSIZE.width-8,SCREENSIZE.height-34);//去除边界和标题栏所占尺寸后的最大尺寸
private Dimension minShowSize = new Dimension(10,10);//组件最小显示尺寸,不过冒似不管用
public FreedomLayout(){
}
public FreedomLayout(Dimension dimension){
minShowSize = dimension;
}
public FreedomLayout(int width , int height){
minShowSize.width = width;
minShowSize.height = height;
}
//添加组件方法
/**
*方法:1.将此组件将加进components这个Vector中。
* 2.将添加进的组件的宽高置为和所指定组件的宽高相等。
*/
public void addLayoutComponent(Component comp , Object constraints){
components.add(new ComponentStruct(counts++,comp,comp.getBounds()));
//判断constraints是否为空,即判断在add()方法中是否有第二个参数
if(constraints!=null){
if(constraints.toString().equals(FIRST)){//判断是否要与第一个组件大小相同
components.get(counts-1).oldRect.width=components.get(0).oldRect.width;//counts-1表示刚添加的这个组件,0表示第一个组件
components.get(counts-1).oldRect.height=components.get(0).oldRect.height;
return;
}
if(constraints.toString().equals(PREVIOUS)){//判断是否要与上一个组件大小相同。
components.get(counts-1).oldRect.width=components.get(counts-2).oldRect.width;////counts-2表示上一个组件
components.get(counts-1).oldRect.height=components.get(counts-2).oldRect.height;
return;
}
if(!constraints.equals(comp)){ //判断add()中的两个参数是否相等,因为刚添加进的这个组件不能与它自己大小相等,它本身可能并未指定大小
for(int i=0 ; i<counts ; i++){ //循环所有组件,
if(constraints.equals(components.get(i).comp)){ //判断是否包含add()中第二个参数的组件,若包含则执行
//将要添加的组件的宽高变为所要指定的组件的宽高
components.get(counts-1).oldRect.width=components.get(i).oldRect.width;
components.get(counts-1).oldRect.height=components.get(i).oldRect.height;
}
}
}
}
}
//设置组件的位置和大小,每当改变框架大小时调用
public void layoutContainer(Container container){
newRect=container.getBounds(); //保存最新的框架大小和坐标。
if(oldRect==null) //保存最初的框架的大小和坐标。
oldRect=newRect;
//每当改变框架大小时,也改变组件的坐标和大小
for(int i=0;i<counts;i++){
components.get(i).comp.setBounds(transfer(components.get(i)));
}
}
//改变组件的大小和坐标
/**
*方法:1.根据oldRect和newRect算出宽和高的比例因子
* 2.根据比例因子计算出组件现在的大小和坐标
*/
public Rectangle transfer(ComponentStruct component){
//计算比例因子
double hFactor = (double)newRect.width / oldRect.width ;
double vFactor = (double)newRect.height / oldRect.height ;
//计算出当前组件的宽高和坐标
Rectangle rect = new Rectangle();
rect.x =(int) (component.oldRect.x * hFactor) ;
rect.y =(int) (component.oldRect.y * vFactor) ;
rect.width =(int) (component.oldRect.width * hFactor) ;
rect.height =(int) (component.oldRect.height * vFactor) ;
return rect;
}
public void addLayoutComponent(String name , Component comp){
//System.out.println("2");
}
//删除组件方法
public void removeLayoutComponent(Component comp){
}
//最大显示尺寸
public Dimension maximumLayoutSize(Container target){
return null;
}
//优选尺寸
public Dimension preferredLayoutSize(Container target){
return null;
}
//最小显示尺寸
public Dimension minimumLayoutSize(Container target){
return minShowSize;
}
//对齐方式
public float getLayoutAlignmentX(Container target){
return 0;
}
public float getLayoutAlignmentY(Container target){
return 0;
}
//清除缓存方式
public void invalidateLayout(Container target){
}
}
/*Test.java*/ import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JFrame{
JButton jb1=new JButton("jb1");
JButton jb2=new JButton("jb2");
JButton jb3=new JButton("jb3");
JButton jb4=new JButton("jb4");
JButton jb5=new JButton("jb5");
public Test(){
Container con = this.getContentPane();
con.setLayout(new FreedomLayout());
//jb1.setBounds(100,100,100,100);
//jb2.setBounds(100,200,200,200);
jb1.setLocation(100,100);
jb2.setLocation(200,100);
jb3.setLocation(300,100);
jb4.setLocation(200,200);
jb5.setLocation(400,200);
jb1.setSize(100,100);
jb4.setSize(150,150);
con.add(jb1);
con.add(jb2,jb1);//表示与jb1这个组件大小相同
con.add(jb3,FreedomLayout.FIRST);//表示与第一组件大小相同
con.add(jb4);
con.add(jb5,FreedomLayout.PREVIOUS);//表示与上一个组件大小相同
this.setBounds(100,100,800,600);//1024-1016=8 768-734=34
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]){
new Test();
}
}
源码下载:http://file.javaxxz.com/2014/11/9/235705390.zip |
|