`
xiaojiit
  • 浏览: 134193 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

Eclipse开发经典教程:SWT布局(2)

    博客分类:
  • Java
阅读更多

GridLayout布局

GridLayout 布局的功能非常强大,也是笔者常用的一种布局方式。GridLayout是网格式布局,它把父组件分成一个表格,默认情况下每个子组件占据一个单元格的空间,每个子组件按添加到父组件的顺序排列在表格中。

GridLayout提供了很多的属性,可以灵活设置网格的信息。另外,GridLayout 布局提供了GridData类,子组件可以设置相应的GridData,例如“dogPhoto.setLayoutData(gridData)”, GridData可以设置每个组件当做单元格的信息。

GridLayout的风格

GridLayout类提供了GridLayout 布局中划分网格的信息,主要通过以下几个参数进行设置。

 NumColumns:通过“gridLayout.numColumns”属性可以设置父组件中分几列显示子组件,如表3所示。

MakeColumnsEqualWidth:通过“gridLayout. makeColumnsEqualWidth”属性可以设置父组件中子组件是否有相同的列宽,当MakeColumnsEqualWidth为true时表示每列的列宽相等。

 ●MarginLeft:表示当前组件距离父组件左边距的像素点个数。
 ●MarginRight:表示当前组件距离父组件右边距的像素点个数。
 ●MarginTop:表示当前组件距离父组件上边距的像素点个数。
 ●MarginBottom:表示当前组件距离父组件下边距的像素点个数。
 ●HorizontalSpacing:表示子组件的水平间距。
 ●VerticalSpacing:表示子组件的垂直间距。

GridData的相关属性

GridLayout布局的灵活之处在于它利用网格布局数据GridData。通过GridData可以设置子组件在网格中的填充方式、大小边距等信息,用户可以通过子组件的setLayoutData方法设置网格布局数据。

GridData可以控制子组件在网格中的位置大小等相关显示信息。GridData可以设置如下的一些属性。

●HorizontalAlignment:表示水平对齐方式。水平对齐方式有如下几种,如表4所示,其中“Button5”按钮显示了水平对齐的方式。
●VerticalAlignment:表示子组件的垂直对齐方式,值和水平方式一样。
●HorizontalIndent:表示子组件水平偏移多少像素。

此属性和“horizontalAlignment = GridData.BEGINNING”属性一起使用。下面代码设置“Button5”水平偏移4像素,如图3所示。

 GridData gridData = new GridData();
gridData.horizontalIndent = 4;
button5.setLayoutData(gridData);

HorizontalSpan:表示组件水平占据几个网格。

此属性非常有用,当要设置一个组件占据几个单元格时,需要设置HorizontalSpan属性。例如,下面代码设置“Button5”按钮水平占据两个网格,如图4所示。

 GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
button5.setLayoutData(gridData);

      
         图3 组件水平偏移                  图4 水平占据网格

 

 ●VerticalSpan:表示组件垂直占据几个网格。
 ●GrabExcessHorizontalSpace:表示当父组件大小改变时,子组件是否以水平方向抢占空间。
 ●GrabExcessVerticalSpace:表示当父组件大小改变时,子组件是否以垂直方向抢占空间。
 ●WidthHint:表示子组件的宽度为多少像素(前提是未设置其他相关属性)。
 ●HeightHint:表示子组件的高度为多少像素(前提是未设置其他相关属性)。

另外,GridData可以通过构造函数指定相应的属性值,有兴趣的读者可以参考GridData类的构造函数。

GridLayout 布局实例

为了更深入地理解GridLayout 布局,下面通过具体的实例演示如何构建一个比较复杂的布局窗口。通过本例的学习,读者可以比较好地掌握GridLayout布局,代码如例程3所示。

例程3 ComplexGridLayoutExample.java

 

 public class ComplexGridLayoutExample {
static Display display;
static Shell shell;
static Text dogName;
static Combo dogBreed;
static Canvas dogPhoto;
static Image dogImage;
static List categories;
static Text ownerName;
static Text ownerPhone;
public static void main(String[] args) {
display = new Display();
shell = new Shell(display);
shell.setText("Dog Show Entry");
//新建GridLayout布局
GridLayout gridLayout = new GridLayout();
//把子组件分成3列显示
gridLayout.numColumns = 3;
shell.setLayout(gridLayout);
new Label(shell, SWT.NONE).setText("Dog's Name:");
dogName = new Text(shell, SWT.SINGLE | SWT.BORDER);
//新建水平填充的GridData
GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
//GridData的组件占两列显示
gridData.horizontalSpan = 2;
dogName.setLayoutData(gridData);
new Label(shell, SWT.NONE).setText("Breed:");
dogBreed = new Combo(shell, SWT.NONE);
dogBreed.setItems(new String [] {"Collie", "Pitbull", "Poodle", "Scottie"});
dogBreed.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
Label label = new Label(shell, SWT.NONE);
label.setText("Categories");
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
new Label(shell, SWT.NONE).setText("Photo:");
dogPhoto = new Canvas(shell, SWT.BORDER);
//gridData两端填充
gridData = new GridData(GridData.FILL_BOTH);
//gridData最佳宽度和高度
gridData.widthHint = 80;
gridData.heightHint = 80;
//设置gridData的子组件垂直占3行
gridData.verticalSpan = 3;
dogPhoto.setLayoutData(gridData);
//添加画布的重画事件
dogPhoto.addPaintListener(new PaintListener() {
public void paintControl(final PaintEvent event) {
if (dogImage != null) {
event.gc.drawImage(dogImage, 0, 0);
}
}
});
categories = new List(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
categories.setItems(new String [] {
"Best of Breed", "Prettiest Female", "Handsomest Male",
"Best Dressed", "Fluffiest Ears", "Most Colors",
"Best Performer", "Loudest Bark", "Best Behaved",
"Prettiest Eyes", "Most Hair", "Longest Tail",
"Cutest Trick"});
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.
VERTICAL_ALIGN_FILL);
gridData.verticalSpan = 4;
int listHeight = categories.getItemHeight() * 12;
Rectangle trim = categories.computeTrim(0, 0, 0, listHeight);
gridData.heightHint = trim.height;
categories.setLayoutData(gridData);
Button browse = new Button(shell, SWT.PUSH);
browse.setText("Browse...");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalIndent = 5;
browse.setLayoutData(gridData);
//添加按钮的选择事件
browse.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
String fileName = new FileDialog(shell).open();
if (fileName != null) {
dogImage = new Image(display, fileName);
dogPhoto.redraw();
}
}
});
Button delete = new Button(shell, SWT.PUSH);
delete.setText("Delete");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.
VERTICAL_ALIGN_BEGINNING);
gridData.horizontalIndent = 5;
delete.setLayoutData(gridData);
delete.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
if (dogImage != null) {
dogImage.dispose();
dogImage = null;
dogPhoto.redraw();
}
}
});
Group ownerInfo = new Group(shell, SWT.NONE);
ownerInfo.setText("Owner Info");
gridLayout = new GridLayout();
gridLayout.numColumns = 2;
ownerInfo.setLayout(gridLayout);
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalSpan = 2;
ownerInfo.setLayoutData(gridData);
new Label(ownerInfo, SWT.NONE).setText("Name:");
ownerName = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
ownerName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
new Label(ownerInfo, SWT.NONE).setText("Phone:");
ownerPhone = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
ownerPhone.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Button enter = new Button(shell, SWT.PUSH);
enter.setText("Enter");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
gridData.horizontalSpan = 3;
enter.setLayoutData(gridData);
enter.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
System.out.println("\nDog Name: " + dogName.getText());
System.out.println("Dog Breed: " + dogBreed.getText());
System.out.println("Owner Name: " + ownerName.getText());
System.out.println("Owner Phone: " + ownerPhone.getText());
System.out.println("Categories:");
String cats[] = categories.getSelection();
for (int i = 0; i < cats.length; i++) {
System.out.println("\t" + cats[i]);
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
if (dogImage != null) {
dogImage.dispose();
}
}
}

程序中构建了一个比较复杂的窗口,设置了GridLayout的布局信息和相关的GridData网格数据信息,程序运行效果如图5所示。


图5 GridLayout布局实例

注意:每个GridData都必须有单独的实例,几个子组件不能够共用同一个GridData(即使几个组件有相同属性的GridData也必须新建几个实例)。

自定义布局

在SWT中,用户可以通过setLayout设置组件的布局信息。布局对象会根据父组件的大小和子组件的布局信息计算出每个子组件的位置和大小,使整个布局空间符合用户的需求。下面将介绍如何创建自己的布局类,实现用户自定义的布局。

Layout类

在SWT中,所有的布局类都继承于Layout抽象类。Layout有两个抽象方法。

 

 1. computeSize (Composite composite, int wHint, int hHint, boolean flushCache)
2. layout (Composite composite, boolean flushCache)

computeSize方法负责计算组件所有子组件所占的高度和宽度,并返回一个Point类型的变量(width,height)。layout方法负责计算子组件的大小和位置,并按计算出来的位置排列子组件。

创建自己的布局类

如果用户希望组件按自己的方式进行布局,可以创建自己的布局类,实现自己的布局。要实现自己的布局,用户要继承Layout类,并实现layout 方法和computeSize方法。下面将实现一个简单的按列进行布局的布局类,在此布局中,所有的子组件将按一列显示,并且子组件的宽度相等,代码如例 程4所示。

例程4 ColumnLayout.java

 

 public class ColumnLayout extends Layout {
public static final int MARGIN = 4;
public static final int SPACING = 2;
Point [] sizes;
int maxWidth, totalHeight;
protected Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
Control children[] = composite.getChildren();
if (flushCache || sizes == null || sizes.length != children.length) {
initialize(children);
}
int width = wHint, height = hHint;
if (wHint == SWT.DEFAULT) width = maxWidth;
if (hHint == SWT.DEFAULT) height = totalHeight;
return new Point(width + 2 * MARGIN, height + 2 * MARGIN);
}
protected void layout(Composite composite, boolean flushCache) {
Control children[] = composite.getChildren();
if (flushCache || sizes == null || sizes.length != children.length) {
initialize(children);
}
Rectangle rect = composite.getClientArea();
int x = MARGIN, y = MARGIN;
//计算最大宽度
int width = Math.max(rect.width - 2 * MARGIN, maxWidth);
for (int i = 0; i < children.length; i++) {
int height = sizes[i].y;
//设置子组件的位置
children[i].setBounds(x, y, width, height);
//计算当前组件的y轴的坐标
y += height + SPACING;
}
}
void initialize(Control children[]) {
maxWidth = 0;
totalHeight = 0;
sizes = new Point [children.length];
for (int i = 0; i < children.length; i++) {
//计算子组件的大小
sizes[i] = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
maxWidth = Math.max(maxWidth, sizes[i].x);
totalHeight += sizes[i].y;
}
totalHeight += (children.length - 1) * SPACING;
}
}

在ColumnLayout类中,通过layout方法对子组件重新计算位置,并设置子组件的位置。为了验证ColumnLayout类,下面通过ColumnLayoutTest类测试ColumnLayout类的效果,代码如例程5所示。

例程5 ColumnLayoutTest.java

 

 public class ColumnLayoutTest {
static Shell shell;
static Button button3;
public static void main(String[] args) {
Display display = new Display();
shell = new Shell(display);
shell.setLayout(new ColumnLayout());
new Button(shell, SWT.PUSH).setText("B1");
new Button(shell, SWT.PUSH).setText("Very Wide Button 2");
(button3 = new Button(shell, SWT.PUSH)).setText("Button 3");
new Text(shell, SWT.NONE).setText("text");
Button grow = new Button(shell, SWT.PUSH);
grow.setText("Grow Button 3");
// 添加选择组件监听器
grow.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
button3.setText("Extreemely Wide Button 3");
//组件大小改变后通知父组件进行重新布局
shell.layout();
shell.pack();
}
});
Button shrink = new Button(shell, SWT.PUSH);
shrink.setText("Shrink Button 3");
shrink.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
button3.setText("Button 3");
//组件大小改变后通知父组件进行重新布局
shell.layout();
shell.pack();
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
}
}


当选择“Grow Button 3”组件后,layout方法会根据子组件的最大宽度调整所有子组件的宽度,程序运行效果如图6所示。

             
原始大小                                           宽度改变后
图6 自己定义布局

本节通过实例介绍了几种常用的布局方式,读者可以通过这几种布局方式实现SWT中大多数的布局需求。另外还有一种常用的布局FormLayout,有兴趣读者可以自行研究,在这里不一一介绍。

如果有某些比较特殊的要求,读者可以尝试修改布局类,以适应相关的布局。读者应该掌握如何设置组件相应的布局信息,掌握如何使用几种方式进行布局,特别是GridLayout布局方式。在有特殊需要的时候要能够修改布局类以适应自己的要求。

分享到:
评论

相关推荐

    Eclipse开发经典教程:SWT布局

    Eclipse开发经典教程,SWT中采用了布局方式,用户可使用布局来控制组件中元素的位置和大小等信息。

    Eclipse开发经典教程:常用SWT组件.pdf

    ### Eclipse开发经典教程:深入解析SWT组件 #### Control类:窗口组件的基石 在探讨SWT(Standard Widget Toolkit)组件之前,理解`Control`类的重要性不容忽视。`Control`作为一个抽象类,充当了所有窗口组件的...

    Eclipse开发经典教程

    通过学习这个经典教程,开发者不仅能熟练使用Eclipse,还能掌握SWT布局的基本原理和技巧,从而提升开发效率,创建出高效、美观的Java应用程序。无论是编写插件、创建自定义界面还是进行代码重构,这些知识都将...

    java eclipse swt教程

    Java Eclipse SWT教程是Java开发中的一个重要领域,主要涉及如何在Eclipse环境中使用SWT(Standard Widget Toolkit)来创建丰富的桌面应用程序界面。SWT是Eclipse基金会推出的一种GUI库,它为Java开发者提供了一种与...

    Java图形界面开发:SWT全接触.pdf

    ### Java图形界面开发:SWT全接触 #### SWT简介 **SWT**(Standard Widget Toolkit)是由Eclipse基金会开发的一套用于构建Java图形用户界面(GUI)的应用程序接口(API)。与传统的Java图形界面开发工具包如AWT...

    SWT开发布局(讲解Eclipse的开发插件)

    【SWT布局详解:Eclipse开发插件使用】 在Java平台上,SWT(Standard Widget Toolkit)是一种用于构建图形用户界面(GUI)的库,它是Eclipse IDE中的核心组成部分。SWT提供了一系列的基础控件和布局管理器,使得...

    swt design for eclipse 3.2

    2. **布局管理**:SWT支持多种布局管理器,如填充布局(FillLayout)、网格布局(GridLayout)、表单布局(FormLayout)等,这些布局管理器帮助开发者有效地组织和定位组件在窗口中的位置。 3. **事件处理**:SWT...

    eclipse插件开发: rcp/swt相关资料

    RCP(Rich Client Platform)和SWT(Standard Widget Toolkit)是Eclipse插件开发中的核心概念。 RCP是Eclipse提供的一种用于构建复杂桌面应用程序的框架。它基于OOP(面向对象编程)原则,提供了可扩展性、模块化...

    eclipse开发SWT应用

    5. **布局管理**:SWT提供了多种布局管理器,如`GridLayout`、`FillLayout`、`RowLayout`等,它们用于决定控件在Shell中的排列方式。通过`setLayout`方法设置Shell或控件的布局。 6. **运行和调试**:在Eclipse中,...

    Eclipse SWT 开发参考

    - **轻量级封装**:SWT对Java GUI库进行了轻量级封装,使其更加贴近本地操作系统的外观和感觉。 - **性能优化**:利用JNI技术,SWT能够更好地处理GUI应用程序中的性能问题。 - **跨平台支持**:虽然SWT具有本地化的...

    Java SWT 图形用户界面教程 PDF

    - **与 Qt、GTK+ 比较**:SWT 提供了Java接口,而Qt和GTK+则需要使用C++或C进行编程,对于Java开发者来说,SWT更易用。 8. **实战演练**: 通过阅读本教程,读者将有机会实践创建简单的SWT应用程序,例如“Hello,...

    org.eclipse.swt相关所有jar包,

    【描述】中的"org.eclipse.swt"是指Eclipse Standard/Widgets工具包,这是一个开源的Java库,允许开发人员在多种平台上创建原生用户界面。它特别强调了JAVA调用IE内核来实现一个内置的浏览器功能,这使得开发者能够...

    SWT开发教程1

    4. SWT布局管理: SWT提供了多种布局管理器,如FillLayout、GridLayout、FormLayout等,它们决定了组件在容器中的排列方式。通过合理地使用布局管理器,开发者可以创建出适应不同屏幕尺寸和分辨率的界面。 5. SWT...

    Eclipse插件开发教程PPT Eclipse插件开发教程PPT

    Eclipse插件开发教程PPT是针对开发者设计的一份详细教学材料,旨在帮助他们了解并掌握如何利用Eclipse平台进行插件开发,从而定制自己的开发环境。以下是基于这个教程的几个关键知识点: 1. **Eclipse插件体系结构*...

    eclipse官方网站上的SWT例子(用306个)

    1. **窗口和布局**:SWT提供各种窗口组件,如Shell、Composite、Group等,以及布局管理器,如FillLayout、GridLayout、MigLayout等,用于组织和控制控件的排列方式。 2. **基本控件**:包括按钮(Button)、文本框...

    eclipse -- swt

    2. **资源管理**:SWT控件和资源需要正确地创建和释放,以防止内存泄漏。 3. **学习曲线**:相比Swing,SWT的学习曲线可能较为陡峭,因为它更底层,需要了解更多的操作系统细节。 **SWT在Eclipse插件开发中的应用:...

    Eclipse+SWTJFace开发实战精解,SWT例子,Eclipse开发入门与项目实践+源代码

    2. **SWT详解**:SWT是Java平台上的一个GUI库,它是Java AWT和Swing的替代品,提供了更接近于原生操作系统界面的用户体验。SWT通过直接操作操作系统API来创建窗口、按钮、文本框等控件,因此其性能优于纯Java实现的...

    org.eclipse.swt.win32

    org.eclipse.swt.browser.PromptService2Factory.class org.eclipse.swt.browser.Prompter.class org.eclipse.swt.browser.SimpleEnumerator.class org.eclipse.swt.browser.StatusTextEvent.class org.eclipse.swt....

    eclipse配置SWT(4/4)

    8. **布局管理**:SWT提供了多种布局管理器,如`FillLayout`、`GridLayout`、`RowLayout`等,用于控制组件在窗口中的排列方式。 9. **国际化支持**:SWT支持资源包(Resource Bundle),可以方便地实现应用程序的多...

Global site tag (gtag.js) - Google Analytics