SWT自定义布局

在写界面的时候布局可谓是个头疼的问题,有的布局方式在一个系统里有,而在另外一个里面就没有,这就是很坑爹的一件事。比如说swing就有BorderLayout,而SWT偏偏又没有,在使用SWT的时候就只能恨恨了。之前在做课程设计的时候恰好在一本书上看到在SWT下自定义的BorderLayout,今天写出来分享分享。

直接上代码

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;


public class BorderLayout extends Layout {

	// 存放在不同位置的5个控件
	private Control north;
	private Control south;
	private Control east;
	private Control west;
	private Control center;

	@Override
	protected Point computeSize(Composite composite, int wHint, int hHint,
			boolean flushCache) {
		// TODO Auto-generated method stub
		getControls(composite);
		// 定义面板的宽和高
		int width = 0, height = 0;
		// 计算面板的宽度
		width += west == null ? 0 : getSize(west, flushCache).x;
		width += east == null ? 0 : getSize(east, flushCache).x;
		width += center == null ? 0 : getSize(center, flushCache).x;
		// 如果上部和下部有控件,则宽度取较大的值
		if (north != null) {
			width = Math.max(width, getSize(north, flushCache).x);
		}
		if (south != null) {
			width = Math.max(width, getSize(south, flushCache).x);
		}
		// 计算面板的高度
		height += north == null ? 0 : getSize(north, flushCache).y;
		height += south == null ? 0 : getSize(south, flushCache).y;
		int heightCenter = center == null ? 0 : getSize(center, flushCache).y;
		if (west != null) {
			heightCenter = Math.max(heightCenter, getSize(west, flushCache).y);
		}
		if (east != null) {
			heightCenter = Math.max(heightCenter, getSize(east, flushCache).y);
		}
		height += heightCenter;

		// 计算的宽和高与默认的宽和高比较,返回较大值
		return new Point(Math.max(width, wHint), Math.max(height, hHint));
	}

	@Override
	protected void layout(Composite composite, boolean flushCache) {
		// TODO Auto-generated method stub
		getControls(composite);
		// 获取当前面板可显示的区域
		Rectangle rect = composite.getClientArea();
		int left = rect.x, right = rect.width, top = rect.y, bottom = rect.height;
		// 将各个控件放置到面板中
		if (north != null) {
			Point pt = getSize(north, flushCache);
			north.setBounds(left, top, rect.width, pt.y);
			top += pt.y;
		}
		if (south != null) {
			Point pt = getSize(south, flushCache);
			south.setBounds(left, rect.height - pt.y, rect.width, pt.y);
			bottom -= pt.y;
		}
		if (east != null) {
			Point pt = getSize(east, flushCache);
			east.setBounds(rect.width - pt.x, top, pt.x, (bottom - top));
			right -= pt.x;
		}
		if (west != null) {
			Point pt = getSize(west, flushCache);
			west.setBounds(left, top, pt.x, (bottom - top));
			left += pt.x;
		}
		if (center != null) {
			center.setBounds(left, top, (right - left), (bottom - top));
		}
	}

	/**
	 * 计算某一控件当前的大小
	 * 
	 * @param control
	 * @param flushCache
	 * @return
	 */
	protected Point getSize(Control control, boolean flushCache) {
		return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
	}

	/**
	 * 设置该类中每个位置控件的属性
	 * 
	 * @param composite
	 */
	protected void getControls(Composite composite) {
		// 获取当前面板中所有的控件对象
		Control[] children = composite.getChildren();
		// 将每个控件所放的位置对号入座
		for (int i = 0; i < children.length; i++) {
			Control child = children[i];
			BorderData borderData = (BorderData) child.getLayoutData();
			if (borderData.region == SWT.TOP)
				north = child;
			else if (borderData.region == SWT.BOTTOM)
				south = child;
			else if (borderData.region == SWT.RIGHT)
				east = child;
			else if (borderData.region == SWT.LEFT)
				west = child;
			else
				center = child;
		}
	}

}

上面是布局Layout,还需要一个设置属性的。

import org.eclipse.swt.SWT;

public final class BorderData {
	
	public int region = SWT.CENTER;//默认为中间
	
	public BorderData(){
	}
	
	public BorderData(int region){
		this.region = region;
	}

}

使用举例:

Composite c = new Composite(parent, SWT.NONE);
c.setLayout(new BorderLayout());

Composite c2 = new Composite(c, SWT.NONE);
c2.setLayoutData(new BorderData(SWT.TOP));

这样就可以显示在父控件的顶部了。

但是这样还不够,用过BorderLayout的人就会发现,上面这种情况在顶部显示的控件高度不能控制,这样对于有些情况就不适用了。

所以下面给出一个比例布局,可以设置两个控件的比例。

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;

/**
 * 按比例布局两个控件
 * 
 * @author Michael
 * 
 */
public class RatioLayout extends Layout {

	private int orientation = SWT.HORIZONTAL;// 默认横向布局

	public float ratio = 1.0f;

	private Control control1;

	private Control control2;

	public RatioLayout() {

	}

	public RatioLayout(int orientation) {
		this.orientation = orientation;
	}

	@Override
	protected Point computeSize(Composite composite, int wHint, int hHint,
			boolean flushCache) {
		// TODO Auto-generated method stub
		return new Point(wHint, hHint);
	}

	@Override
	protected void layout(Composite composite, boolean flushCache) {
		// TODO Auto-generated method stub
		getControls(composite);
		// 当前面板的可显示区域
		Rectangle rect = composite.getClientArea();
		int x = rect.x, y = rect.y, width = rect.width, height = rect.height;
		if (orientation == SWT.HORIZONTAL) {// 横向布局
			if (control1 != null) {
				control1.setBounds(x, y, (int) (width * ratio), height);
			}
			if (control2 != null) {
				control2.setBounds((int) (width * ratio), y,
						(int) (width * (1 - ratio)), height);
			}
		}
		if (orientation == SWT.VERTICAL) {// 纵向布局
			if (control1 != null) {
				control1.setBounds(x, y, width, (int) (height * ratio));
			}
			if (control2 != null) {
				control2.setBounds(x, (int) (height * ratio), width, (int) (height * (1 - ratio)));
			}
		}

	}

	// 获取所有控件对象
	protected void getControls(Composite composite) {
		Control[] children = composite.getChildren();
		if (children.length > 2) {
			return;
		}
		try {
			control1 = children[0];
			control2 = children[1];
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO: handle exception
			return;
		}
	}

}

上面这种方式只能容纳两个控件,使用方式如下:

RatioLayout ratioLayout = new RatioLayout(SWT.VERTICAL);
ratioLayout.ratio = 0.2f;

好了,就介绍这两种布局。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值