`
eclipsesbs
  • 浏览: 20359 次
社区版块
存档分类
最新评论

第五天:控件布局怎么这么麻烦

阅读更多

作者:梁祺 (eclipsesbs@gmail.com)

 

来自:http://www.benisoft.net/day5/index.html

 

在UI应用程序开发中,控件的布局是一个比较重要的方面,也另初学者很是头疼。 Eclipse并没有象其他开发工具那样提供图形化工具,允许程序员通过拖拽控件来进行布局。 不过有不少第三方为Eclipse提供商业的或非商业的图形化布局的工具。虽然直接写代码布局控件比较麻烦, 但也有它的好处,后期维护阶段,不需要读懂工具自动生成的晦涩的代码。 今天就来看一下Eclipse的控件布局是怎样的。

Eclipse的SWT(Standard Widget Toolkit)提供的基本布局有FillLayout,RowLayout, FormLayout和GridLayout,都在org.eclipse.swt.layout这个包里。前三种布局方式只能满足简单的布局需要, 略有些复杂的布局就无法单独胜任了。而GridLayout非常强大,任何的控件布局需求它都能满足, 所以这里只介绍GridLayout。从软件工程的角度出发, 使用五花八门的布局方式,并不是一件好事,这意味着整个Team对不同的布局都有所了解, 否则,修改一个你不熟悉的布局方式将是件非常痛苦的事。所以个人建议是在任何情况下都使用GridLayout, 并贯彻到整个Team,这样就可以减轻维护的工作量。

GridLayout的基本思想是把整个矩形布局区域划分成M*N的格子, 它允许将同一行或同一列相邻的格子合并成一个格子放置控件。 通过Composite/Group等容器控件,并且在容器控件内继续使用GridLayout布局控件, 我们就能够完成任何形式的UI布局。以下面这个对话框为例。

这个对话框有三个Group控件,分别是Properties,Options,和Rich Client Application, 这三个Group控件构成了一个三行一列的表格。

  • 在Properties里面,每一行表示一个属性,除了最后一行有三个控件, 其他都是两个控件,我们可以把它看成是五行三列的表格,前面四行的第二个控件占两列,第五行的控件各占一列。
  • 第二个Options也类似,可以看成四行三列的表格,其中第二行用一个空的Label来占住第一列, 剩下两个控件各占一列。
  • 最后Rich Client Application就是一个一行三列的表格,三个控件各占一列。

首先来创建一个Plug-in项目,输入项目名”eclipse.tutorial.day5“,我们仍然用Hello World这个例子, 只不过把SampleAction的run()方法改成打开LayoutDialog。

    public void run(IAction action) {
        LayoutDialog dialog = new LayoutDialog(window.getShell());
        dialog.open();
    }

接下来我们来创建LayoutDialog类,点击工具栏上的"New Java Class"按钮。

在New Java Class对话框里输入包名为"eclipse.tutorial.day4.actions",类名为"LayoutDialog", 继承自”org.eclipse.jface.dialogs.Dialog“,点击Finish。

LayoutDialog继承自Dialog,它重载createDialogArea()方法,这个方法有一个参数, 提供一个容器用于放置我们想要创建的控件,一般我们都会创建一个Composite容器控件占满整个parent, 然后我们就可以为composite指定我们需要的布局方式。在这个例子中,需要从上到下创建三个Group控件, 是一个三行一列的表格,所以我们指定布局为GridLayout(只有一列), GridLayout的构造函数的第一个参数是表格的列数, 第二个参数是表格的每列是否等宽,既然只有一列,也无所谓等不等宽了,所以true和false都可以。 将layout对象通过setLayout()方法设置为composite的布局, 同时我们也要指定调用setLayoutData()设置composite在parent中的位置。 顺便说一下,基类Dialog将composite的布局方式为GridLayout。

public class LayoutDialog extends Dialog {

    protected LayoutDialog(Shell parentShell) {
        super(parentShell);
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, true);
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, truetrue, 1, 1));

      ...        
        return composite;
    }
}

下面我们看一下GridData,GridData有不少构造函数,其实我们只要记住下面这个就行了,以不变应万变。

public GridData (int horizontalAlignment, int verticalAlignment, 
                boolean grabExcessHorizontalSpace, boolean grabExcessVerticalSpace, 
                int horizontalSpan, int verticalSpan) 

 

  • HorizontalAlignment: 水平方向左对齐,居中对齐,右对齐,或者充满整个格子。分别是 SWT.BEGINNING/CENTER/END/FILL。
  • verticalAlignment:垂直方向上对齐,居中对齐,下对齐,或者充满整个格子。分别是 SWT.BEGINNING/CENTER/END/FILL。
  • grabExcessHorizontalSpace:水平方向空间增加时,是否占据整个水平方向的空间。比如,当用户拖大对话框, 这个参数为true的空间将占据增加的部分。
  • grabExcessVerticalSpace:垂直方向空间增加时,是否占据整个水平方向的空间。
  • horizontalSpan: 空间在水平方向上占几个格子。
  • verticalSpan: 空间在垂直方向上占几个格子。

所以composite占据1x1的格子,SWT.FILL说明它在两个方向都是充满整个格子,并且如果格子尺寸变大, 它在两个方向都会占据新增加的部分。

        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, truetrue, 1, 1));

接下来看看各个控件是怎么布局的,整个代码比较长,我们先看看三个Group,它们的代码很类似, 设置了相同的LayoutData,都占据一个1x1的格子,水平方向充满整个格子,垂直方向上对齐,格子尺寸变化时, 水平方向占据新空间。它们也都将自己内部的布局方式设置为GridLayout,根据前面的分析,都是三列,列宽不要求相同。

        // Properties Group
        Group group1 = new Group(composite, SWT.NONE);
        group1.setText(\"Properties\");
        group1.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, truefalse, 1, 1));
        group1.setLayout(new GridLayout(3, false));
        
        // Options Group
        Group group2 = new Group(composite, SWT.NONE);
        group2.setText(\"Options\");
        group2.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, truefalse, 1, 1));
        group2.setLayout(new GridLayout(3, false));
        
        // Rich Client Application Group
        Group group3 = new Group(composite, SWT.NONE);
        group3.setText(\"Rich Client Application\");
        group3.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, truefalse, 1, 1));
        group3.setLayout(new GridLayout(3, false));

再看一下Properties Group的第一行,label和text。label放在1x1的格子里,左对齐,上对齐,格子大小改变时, 控件尺寸不变。text放在2x1的格子里,充满水平方向,格子尺寸改变时,控件水平方向尺寸作相应的改变。

        Label label = new Label(group1, SWT.NONE);
        label.setText(\"ID: \");
        label.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, falsefalse, 1, 1));
        Text text = new Text(group1, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, truefalse, 2, 1));

再看一下Options Group的第二行,第一个label是一个占位控件,本身没有任何用处,就是为了占住这行的第一格, 以便Activator从第二列开始,看起来像从属于上一行的控件。因为占位控件没有文字, 并且它是第一列中唯一独占第一列的控件(其他都不单独属于第一列),所以它的宽度就决定了第一列的尺寸, 就需要为它指定宽度,否则第一列的宽度就变成0了(不考虑列边距)。这里我们设置它的宽度widthHint为10。

        label = new Label(group2, SWT.NONE);
        GridData layoutData = new GridData(SWT.BEGINNING, SWT.BEGINNING, falsefalse, 1, 1);
        layoutData.widthHint = 10;
        label.setLayoutData(layoutData);
        label = new Label(group2, SWT.NONE);
        label.setText(\"Activator: \");
        label.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, falsefalse, 1, 1));
        text = new Text(group2, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, truefalse, 1, 1));

其它几个控件的布局,这里就不一一介绍了。

这个例子我们可以看到,使用GridLayout和容器控件(Composite和Group),我们可以构造任何形式的布局。 不过在动手之前,还是强烈建议画一个草图,确定每个GridLayout是几行几列,每个控件在水平方向和垂直方向各占几格, 是否需要填充格子,还是左对齐,右对齐,格子尺寸变化时,控件是否需要改变尺寸。如果控件位置不理想, 在后续开发中发现需要作重大调整的话,工作量还是挺大的,要比图形化布局编辑器要麻烦。那么适当的注释也很必要, 标记出控件之间的层次关系,便于理解。另外控件的布局也需要不断的调试,在运行态观察布局是否清晰,合理,美观。

分享到:
评论

相关推荐

    如何在MATLAB中做出标签页的效果-tabpanel2.6.zip

    tabpanel,第一个参数是figure的名字,第二个参数是刚才加入的text控件的tag。这时候等侯一下,会出现一个运行的figure和一个小面板,在面板上有几项分别是(从上到下从左到右)添加标签、编辑标签、更新标签、当前...

    Android APP基本框架的搭建

    进入主页面后设置里的布局,要用线性布局,因为要用到权重,只有线性布局有,用相对布局反而麻烦线性布局或者相对布局总体是线性布局。 八、实现标题栏 首先写标题栏,用 include 的方式,因为以后标题栏可能会...

    ExtAspNet_v2.3.2_dll

    -Grid中TemplateField生成到页面中控件具有唯一ID,例如Grid1_ct5_Label2,Grid1_ct6_Label2(feedback:geruger)。 +2009-09-27 v2.1.2 -为Tree控件增加GetExpandAllNodesReference和...

    ExtAspNet v2.2.1 (2009-4-1) 值得一看

    -Button控件将不再自动拥有display:inline属性,如果希望两个按钮在一行显示,请为第一个按钮设置CssStyle="float:left;"属性。 -修正了弹出菜单的位置在Firefox下不正确的BUG(feedback:eroach)。 -为TriggerBox...

    SuperTextView-从未如此惊艳!一个超级的TextView.zip

    简介欢迎使用SuperTextView,这篇文档将会向你展示如何使用这个控件来提高你构建项目的效率。CoverSuperTextView继承自TextView,它能够大量的减少布局的复杂程度,并且使得一些常见的效果变得十分容易实现且高效。...

    手机wrap网站仿北京房地产交易网触屏版html5手机wap房产网站模板下载(超动感)

    1. **HTML5**:HyperText Markup Language 5(超文本标记语言第五版),是用于创建网页的标准标记语言之一。HTML5 相比于之前的版本,在多媒体支持、表单控件、离线存储、设备访问等方面有了显著增强。 - 多媒体...

    c#程序设计经典教程第三版(含例题和实验)

    16. Windows Forms与WPF:学习如何使用Windows Forms或WPF构建图形用户界面,掌握控件布局和事件处理。 17. ADO.NET:理解数据库连接、命令执行、数据集和数据适配器的使用,实现数据的CRUD操作。 18. ASP.NET Web...

    2021-2022计算机二级等级考试试题及答案No.11959.docx

    - 浪费存储空间及修改麻烦:因为相同的数据被多次存储,增加了存储空间的占用,并且在更新数据时可能需要同时修改多份拷贝。 - 潜在的数据不一致性:如果某个副本的数据被更新而其他副本没有同步更新,就会导致...

    资源LJ化学品1源码

    1. **控件和布局**:WinForms中包含各种控件,如按钮、文本框、列表视图等,它们用于接收用户输入和显示信息。源代码会描述如何在窗体上布置这些控件,以及它们之间的交互逻辑。 2. **事件处理**:每个控件都有与其...

    第14章 水晶报表第14章 水晶报表第14章 水晶报表

    ### 第14章 水晶报表:深入理解与应用 水晶报表(Crystal Reports)作为一款功能强大的报表设计工具,在企业级应用开发中扮演着重要角色。本章节将重点介绍水晶报表的基础知识、结构特点以及如何在Visual Studio ...

    2021-2022计算机二级等级考试试题及答案No.13150.docx

    - **解答**:数据冗余可能导致的主要问题是浪费存储空间及修改麻烦、潜在的数据不一致性。 ### 17. 表中建立索引 - **知识点**:题目询问的是在表中建立索引的命令。 - **解答**:在数据库中建立索引通常使用的命令...

    Java核心技术第12版(卷1+卷2)

    9. **JavaFX**:Java的GUI库,用于构建桌面应用程序,包括控件、布局、事件处理等。 这两卷书详细且深入地讲解了Java编程的各个方面,无论你是初学者还是有经验的开发者,都能从中获取宝贵的知识和实践经验。通过...

    如何在MATLAB中做出标签页的效果-tabgui.m

    tabpanel,第一个参数是figure的名字,第二个参数是刚才加入的text控件的tag。这时候等侯一下,会出现一个运行的figure和一个小面板,在面板上有几项分别是(从上到下从左到右)添加标签、编辑标签、更新标签、当前...

    如何在MATLAB中做出标签页的效果-test.m

    tabpanel,第一个参数是figure的名字,第二个参数是刚才加入的text控件的tag。这时候等侯一下,会出现一个运行的figure和一个小面板,在面板上有几项分别是(从上到下从左到右)添加标签、编辑标签、更新标签、当前...

    如何在MATLAB中做出标签页的效果-tab.rar

    tabpanel,第一个参数是figure的名字,第二个参数是刚才加入的text控件的tag。这时候等侯一下,会出现一个运行的figure和一个小面板,在面板上有几项分别是(从上到下从左到右)添加标签、编辑标签、更新标签、当前...

    C#入门经典

    8. **Windows Forms和WPF**:这两部分会讲解如何使用C#开发图形用户界面(GUI)应用程序,包括控件使用、事件处理、布局管理等。 9. **ASP.NET Web应用**:对于想要开发Web应用的读者,书中的这部分内容将介绍如何...

    Book-Recommend-Github:推荐生活当中积累的优秀Objective-C和Swift三方库

    基于Objective-C以及Swift进行的相关推荐,常用程度:1-5星。 每天会不定时更新,推荐好玩有趣的第三方优秀框架。 麻烦给小编一颗:glowing_star:,让小编更有动力总结出更多优秀文章和作品。 Objective-C Swift ...

    CodematicDemoMVC

    没有使用view state和服务器表单控件,可以更方便的控制 应用程序的行为 应用程序通过controller来控制程序请求,可以 提供丰富的url重写 支持测试驱动开发 在团队模式下表现更加出众 关注点分离 高扩展性 ...

    《OceanX》播放器 Prv0.34

    4,修正了按钮的三种背景的更换出现延迟的现象(加入了图片的预载功能)5,URL输入窗口增加面向使用用户的制定选择播放控件的功能!!6,更正了URL输入地址完毕后,对一些地址的误判断错误!!7,更正了选择歌曲窗口的...

    《OceanX》播放器 Prv0.33

    4,修正了按钮的三种背景的更换出现延迟的现象(加入了图片的预载功能)5,URL输入窗口增加面向使用用户的制定选择播放控件的功能!!6,更正了URL输入地址完毕后,对一些地址的误判断错误!!7,更正了选择歌曲窗口的...

Global site tag (gtag.js) - Google Analytics