SWT自定义布局

来源:互联网 发布:如何开淘宝店铺 编辑:程序博客网 时间:2024/06/03 12:55

在写界面的时候布局可谓是个头疼的问题,有的布局方式在一个系统里有,而在另外一个里面就没有,这就是很坑爹的一件事。比如说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;@Overrideprotected Point computeSize(Composite composite, int wHint, int hHint,boolean flushCache) {// TODO Auto-generated method stubgetControls(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));}@Overrideprotected void layout(Composite composite, boolean flushCache) {// TODO Auto-generated method stubgetControls(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;elsecenter = 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;}@Overrideprotected Point computeSize(Composite composite, int wHint, int hHint,boolean flushCache) {// TODO Auto-generated method stubreturn new Point(wHint, hHint);}@Overrideprotected void layout(Composite composite, boolean flushCache) {// TODO Auto-generated method stubgetControls(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 exceptionreturn;}}}

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

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

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




0 0