当前页面: 开发资料首页 → Eclipse 专题 → Eclipse Forms: 为胖客户端做的漂亮UI(翻译,第二部分)
摘要: Eclipse Forms: 为胖客户端做的漂亮UI(翻译,第二部分)
增加一些内容
现在我们已经有一个view能够成功运行了.我们可以往里面增加一
public void createPartControl(Composite parent) { toolkit = new FormToolkit(parent.getDisplay()); form = toolkit.createForm(parent); form.setText("Hello, Eclipse Forms"); GridLayout layout = new GridLayout(); form.getBody().setLayout(layout); Hyperlink link = toolkit.createHyperlink(form.getBody(), "Click here.", SWT.WRAP); link.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent e) { System.out.println("Link activated!"); } }); }
form的body是标题下面的可用空间.因为这个空间是一个SW
超链接组(Hyperlink Groups)
Form tookit有一个"超链接组"对象.每个创建出的超链接都加入这个组对象中.超链接为多个角色服
当你要改变超链接组对象的默认设置时,可以通过toolkit的g
D(["mb","创建普通组件
\nEclipse Forms的一个设计目标就是让能够在编辑器/视图中创建普通SWlayout.numColumns \u003d 2;\n GridData gd \u003d new GridData();\n gd.horizontalSpan \u003d 2;\n link.setLayoutData(gd);\n Label label \u003d new Label(form.getBody(), SWT.NULL);\n label.setText("Text field label:");\n Text text \u003d new Text(form.getBody(), SWT.BORDER);\n text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\n Button button \u003d new Button(form.getBody(), SWT.CHECK);\n button.setText("An example of a checkbox in a form");\n gd \u003d new GridData();\n gd.horizontalSpan \u003d 2;\n button.setLayoutData(gd);
Label label \u003d toolkit.createLabel(form.getBody(), "Text field label:");\n Text text \u003d toolkit.createText(form.getBody(), "");\n text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\n Button button \u003d toolkit.createButton(form.getBody(), "A checkbox in a form", SWT.CHECK);\n gd \u003d new GridData();\n gd.horizontalSpan \u003d 2;\n button.setLayoutData(gd);\n这个视图现在会看来更好些了:\n?\n
达到"平滑"的视觉效果",1] ); // 创建普通组件
Eclipse Forms的一个设计目标就是让能够在编辑器/视图中创建普通SWlayout.numColumns = 2; GridData gd = new GridData(); gd.horizontalSpan = 2; link.setLayoutData(gd); Label label = new Label(form.getBody(), SWT.NULL); label.setText("Text field label:"); Text text = new Text(form.getBody(), SWT.BORDER); text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Button button = new Button(form.getBody(), SWT.CHECK); button.setText("An example of a checkbox in a form"); gd = new GridData(); gd.horizontalSpan = 2; button.setLayoutData(gd);
Label label = toolkit.createLabel(form.getBody(), "Text field label:"); Text text = toolkit.createText(form.getBody(), ""); text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Button button = toolkit.createButton(form.getBody(), "A checkbox in a form", SWT.CHECK); gd = new GridData(); gd.horizontalSpan = 2; button.setLayoutData(gd);这个视图现在会看来更好些了:
达到"平滑"的视觉效果 D(["mb","
\n一个在PDE编辑器中Eclipse Forms的可看出的属性是组件的"平滑"视觉效果.以前所有没有3D边框的组件在窗口中看起来不错,但是在编辑器或视图中就不行.这个支持写在FormToolkit
Form toolkit知道哪个组件需要一个定制的边框.但是,你可能新创建了一个不在原来名单中的组件,它也需要一个边框.你可以通过象下面这样的代码给toolkit一
Control myControl \u003d new MyControl(parent);\nmyControl.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);\n// or myControl.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);\ntoolkit.paintBordersFor(parent);\n
你可以在上面这张图中看出,象树和表格这样的"结构化
?因为Eclipse 3.0和在Windows XP上,当javaw.exe.manifest文件在Java虚拟机bi
定制布局(Custom layouts)
Eclipse Forms在SWT layout的基础上增加了两个新的layout
一个在PDE编辑器中Eclipse Forms的可看出的属性是组件的"平滑"视觉效果.以前所有没有3D边框的组件在窗口中看起来不错,但是在编辑器或视图中就不行.这个支持写在FormToolkit
Form toolkit知道哪个组件需要一个定制的边框.但是,你可能新创建了一个不在原来名单中的组件,它也需要一个边框.你可以通过象下面这样的代码给toolkit一
Control myControl = new MyControl(parent); myControl.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); // or myControl.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); toolkit.paintBordersFor(parent);
你可以在上面这张图中看出,象树和表格这样的"结构化
因为Eclipse 3.0和在Windows XP上,当javaw.exe.manifest文件在Java虚拟机bi
定制布局(Custom layouts)
Eclipse Forms在SWT layout的基础上增加了两个新的layout
发生什么事了?记住我们使用的是GridLayout
我们需要的是一个象HTML表格一样的layout
但是,它们在布局时完全不同.TableWrapLayout从列开始
public void createPartControl(Composite parent) {\n toolkit \u003d new FormToolkit(parent.getDisplay());\n form \u003d toolkit.createForm(parent);\n form.setText("Hello, Eclipse Forms");\n TableWrapLayout layout \u003d new TableWrapLayout();\n form.getBody().setLayout(layout);\n Hyperlink link \u003d toolkit.createHyperlink(form.getBody(),"Click here.", SWT.WRAP);\n link.addHyperlinkListener(new HyperlinkAdapter() {\n public void linkActivated(HyperlinkEvent e) {\n System.out.println("Link activated!");\n }\n });\n link.setText("This is an example of a form that is much longer and will need to wrap.");\n layout.numColumns \u003d 2;\n TableWrapData td \u003d new TableWrapData();\n td.colspan \u003d 2;\n link.setLayoutData(td);\n Label label \u003d toolkit.createLabel(form.getBody(), "Text field label:");\n Text text \u003d toolkit.createText(form.getBody(), "");\n td \u003d new TableWrapData(TableWrapData.FILL_GRAB);\n text.setLayoutData(td);\n Button button \u003d toolkit.createButton(form.getBody(), "A checkbox in a form", ",1] ); //
"and will need to wrap.");
让我们看看结果:
图片7:一个使用GridLayout的form发生什么事了?记住我们使用的是GridLayout
.当它问这个超链接组件来计算它大小时,超链接告诉它文字在单独行里需要的长度.虽然我们告诉组件去包裹(wrap),它并没有这样做因为GridLayout需要组件返回它的长度 .超连接组件--和其它象Label一样的SWT组件,可以通过你传递它数值来决定 长和宽,但是GridLayout不会向组件传递数值参数. 我们需要的是一个象HTML表格一样的layout
.我们希望内容去试图配合提供的客户空间,并且一行行地叠加.Eclipse Forms提供了一个这样的layout叫TableWrapLa yout.GridLayout和TableWrapLayout 之间有许多共同点.都是用表格来组织parent的childre n.都有layout data来告诉layout如何对待每个组件.都能够在需要占据所 有空间时等接受组件的提示. 但是,它们在布局时完全不同.TableWrapLayout从列开始
让我们使用TableWrapLayout来重新更改例子.它计算每列的最小的,合适的,最大的宽度并用这个信息来占据空间.它也试图尽可能地公平地在各列 间分隔,这样有些组件就没有多余的空间. (更改处高亮显示): public void createPartControl(Composite parent) { toolkit = new FormToolkit(parent.getDisplay()); form = toolkit.createForm(parent); form.setText("Hello, Eclipse Forms"); TableWrapLayout layout = new TableWrapLayout(); form.getBody().setLayout(layout); Hyperlink link = toolkit.createHyperlink(form.getBody(),"Click here.", SWT.WRAP); link.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent e) { System.out.println("Link activated!"); } }); link.setText("This is an example of a form that is much longer and will need to wrap."); layout.numColumns = 2; TableWrapData td = new TableWrapData(); td.colspan = 2; link.setLayoutData(td); Label label = toolkit.createLabel(form.getBody(), "Text field label:"); Text text = toolkit.createText(form.getBody(), ""); td = new TableWrapData(TableWrapData.FILL_GRAB); text.setLayoutData(td); Button button = toolkit.createButton(form.getBody(), "A checkbox in a form", D(["mb","SWT.CHECK);\n td \u003d new TableWrapData();\n td.colspan \u003d 2;\n button.setLayoutData(td);\n }
我们用了GridData相同的概念.一些变量拥有不同的名字(举个例子,colspan和rowspan,align和valign取自HTML TABLE的属性),但是你可以做相同的事--创建一个超链接和按钮占据两列的格子 .因为空白(margins)和GridLayout是相同的 ,结果会看起来一样,除了超链接现在会包裹起来: \n\n
图片8:一个使用TableWrapLayout的formTableWrapLayout和GridLayout的一个主要
\n的不同点是你应该停止去计算垂直的空间.在GridLayout里,你一般会让"不易变形的(rigid)"组件用自然的位置和大小 并让"可伸缩的(flexible)"组件去占据水平或垂直的空间.相反,TableWrapLayout是从上往下工作的 ,并且它容下所有的组件,它的工作是完全的.占据水平空间的概念还存在(象上面展示一样).但是,垂直方向上,你只能在单元(cell )比组件高时选择FILL单元,或选择TOP,MIDDLE或BO TTOM垂直对齐.\n
你也许会注意到一个地方和刚刚说的不符:TableWrapLayout仍然有一个grabVertical变量.但是 ,这里这个变量在这里有明确的目的:当一个设置了高度的组件占多行 时,它的高度会给出一个条件就是垂直dimension已经知道了 ,组件需要去除它所在的多个单元之间的多余空间. 为了用TableWrapLayout有好的结果
\n,确定组件可以接近风格(SWT.WRAP).Eclipse Froms提供的组合定制组件能够在box外面包裹 .这是通过实现ILayoutExtension接口实现的:
public interface ILayoutExtension {
?? /**
??? * Computes the minimum width of the parent. All widgets capable of word\n
??? * wrapping should return the width of the longest word that cannot be
??? * broken any further.
??? *
??? * @param parent the parent composite
??? * @param changedtrue
if the cached information should be\n
??? * flushed,false
otherwise.
??? * @return the minimum width of the parent composite
??? */
?? public int computeMinimumWidth(Composite parent, boolean changed);?? /**
??? * Computes the maximum width of the parent. All widgets capable of word
??? * wrapping should return the length of the entire text with wrapping
??? * turned off.
??? *
??? * @param parent the parent composite\n
??? * @param changedtrue
if the cached information
??? * should be flushed,false
otherwise.",1] ); //SWT.CHECK); td = new TableWrapData(); td.colspan = 2; button.setLayoutData(td); }
我们用了GridData相同的概念.一些变量拥有不同的名字(举个例子,colspan和rowspan,align和valign取自HTML TABLE的属性),但是你可以做相同的事--创建一个超链接和按钮占据两列的格子 .因为空白(margins)和GridLayout是相同的 ,结果会看起来一样,除了超链接现在会包裹起来:
图片8:一个使用TableWrapLayout的form
TableWrapLayout和GridLayout的一个主要
你也许会注意到一个地方和刚刚说的不符:TableWrapLay
为了用TableWrapLayout有好的结果
public interface ILayoutExtension {
/**
* Computes the minimum width of the parent. All widgets capable of word
* wrapping should return the width of the longest word that cannot be
* broken any further.
*
* @param parent the parent composite
* @param changed true
if the cached information should be
* flushed, false
otherwise.
* @return the minimum width of the parent composite
*/
public int computeMinimumWidth(Composite parent, boolean changed);
/**
* Computes the maximum width of the parent. All widgets capable of word
* wrapping should return the length of the entire text with wrapping
* turned off.
*
* @param parent the parent composite
* @param changed true
if the cached information
* should be flushed, false
otherwise.
D(["mb","
??? * @return the maximum width of the parent composite
??? */
\n?? public int computeMaximumWidth(Composite parent, boolean changed);
}
TableWrapLayout本身实现了这个接口,这样让它处理当composites的layout是这个comp
layout.numColumns \u003d 3;\n Label label;\n TableWrapData td;\n \n label \u003d toolkit.createLabel(form.getBody(), \n "Some text to put in the first column", SWT.WRAP);\n label \u003d toolkit.createLabel(form.getBody(),\n "Some text to put in the second column and make it a bit "+\n "longer so that we can see what happens with column "+\n distribution. This text must be the longest so that it can "+\n "get more space allocated to the columns it belongs to.", \n SWT.WRAP);\n td \u003d new TableWrapData();\n td.colspan \u003d 2;\n label.setLayoutData(td);\n label \u003d toolkit.createLabel(form.getBody(), \n "This text will span two rows and should not grow the column.", \n SWT.WRAP);\n td \u003d new TableWrapData();\n td.rowspan \u003d 2;\n label.setLayoutData(td);\n label \u003d toolkit.createLabel(form.getBody(), \n "This text goes into column 2 and consumes only one cell", \n SWT.WRAP);\n label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));\n label \u003d toolkit.createLabel(form.getBody(), \n "This text goes into column 3 and consumes only one cell too", \n SWT.WRAP);\n label.setLayoutData(new TableWrapData(TableWrapData.FILL));\n label \u003d toolkit.createLabel(form.getBody(), \n "This text goes into column 2 and consumes only one cell", \n SWT.WRAP);\n label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));\n label \u003d toolkit.createLabel(form.getBody(), \n "This text goes into column 3 and consumes only one cell too", \n SWT.WRAP);\n label.setLayoutData(new TableWrapData(TableWrapData.FILL));\n",1] ); //
* @return the maximum width of the parent composite
*/
public int computeMaximumWidth(Composite parent, boolean changed);
}
TableWrapLayout本身实现了这个接口,这样让它处理当composites的layout是这个composite的parent的children的情况 .另外的两个方法能够计算两种极端情况--当所有组件尽可能宽地布满时的显然的最小宽度和最大宽度 .两者的不同是使列之间的多余空间尽可能小时贡献出公平的空间. 让我们看清楚贡献空间是怎样的.我们会推荐我们到现在为止写的代码并象下面这样做出修改: layout.numColumns = 3; Label label; TableWrapData td; label = toolkit.createLabel(form.getBody(), "Some text to put in the first column", SWT.WRAP); label = toolkit.createLabel(form.getBody(), "Some text to put in the second column and make it a bit "+ "longer so that we can see what happens with column "+ distribution. This text must be the longest so that it can "+ "get more space allocated to the columns it belongs to.", SWT.WRAP); td = new TableWrapData(); td.colspan = 2; label.setLayoutData(td); label = toolkit.createLabel(form.getBody(), "This text will span two rows and should not grow the column.", SWT.WRAP); td = new TableWrapData(); td.rowspan = 2; label.setLayoutData(td); label = toolkit.createLabel(form.getBody(), "This text goes into column 2 and consumes only one cell", SWT.WRAP); label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); label = toolkit.createLabel(form.getBody(), "This text goes into column 3 and consumes only one cell too", SWT.WRAP); label.setLayoutData(new TableWrapData(TableWrapData.FILL)); label = toolkit.createLabel(form.getBody(), "This text goes into column 2 and consumes only one cell", SWT.WRAP); label.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); label = toolkit.createLabel(form.getBody(), "This text goes into column 3 and consumes only one cell too", SWT.WRAP); label.setLayoutData(new TableWrapData(TableWrapData.FILL)); D(["mb"," form.getBody().setBackground(form.getBody().getDisplay().\n getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
这个创建了一些有不同长度文本的label.有些labels占据多列,有些占据多行.为了让测试更加简单,\n我们把form的背景设置为组件背景,这样单元能够更简单看出来.当我们运行例子,我们会得到下面的样子: \n\n
图片9:TableWrapLayout留下的多余空间关键之处在于组件最小宽度和最大宽度相比较时.相差越多,结果越明显,会看到列中有很大的缝隙.占据的宽度是组件所需要的最小的宽度
\n.注意第3列比第2列稍微宽一点点,这是因为第3列中的文字长度比第2列中文字要长点 .如果需要阅读布局的相关理论,可以去这里W3C recommendations for HTML table auto-layout. ColumnLayout
\n
Eclipse Forms另外一个定制的layout是SWT RowLayout的变种.如果我们把RowLayout上的children垂直放置时--按列-并且使同列中的所有组件拥有相同的宽度,我们会由组件的宽度得到多个列.但是,最后一列显然不是被填满的--这由组件的个数决定 .如果在form中,我们会仍然看到所有组件在一列中,因为RowLayout不能够 "垂直"\n包裹.如果我们用GridLayout相替代的话,列的数量由我们自己决定. 在更加复杂的forms中我们需要列的数量按情况变化.换句话来说,我们希望数字按照form的宽度来改变--有可能需要更多的列,当宽度减小时则把数字减小.而且我们希望所有列的长度象报纸布局一
\n样相同.这些要求都能够通过ColumnLayout来达到. 与TableWrapLayout相比,ColumnLayout更加简单.不需要复杂的设置
\n?\n\n图片10:使用ColumnLayout的所有按列排列的段落.唯一需要你设置的就是列数的范围,默认是1到3.下面的例子演示了一个使用ColumnLayout 的有许多段落(sections)的form.初始时,只需要两列就可以放置所有段落了.如果我们把编辑器变窄一点,layout会使它们在同一列中. .layout开始是两列,但是按照空间的改变变成了一列.\n 高级组件(Complex controls)
\n
Eclipse Forms提供了4个高级组件,这样你能够构建漂亮的UI:expandable composite,section,image hyperlink和form text.让我们依次仔细看看它们每一个. Expandable composite
在网页中有个普遍的功能就是让你有能力把一部分网页内容用一个按钮来伸缩它.Eclipse Forms提供了这样一个组件:ExpandableCompos ite. ExpandableComposite ec \u003d toolkit.createExpandableComposite(form.getBody",1] ); // form.getBody().setBackground(form.getBody().getDisplay(). getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
这个创建了一些有不同长度文本的label.有些labels占据多列,有些占据多行.为了让测试更加简单, 我们把form的背景设置为组件背景,这样单元能够更简单看出来.当我们运行例子,我们会得到下面的样子:
图片9:TableWrapLayout留下的多余空间关键之处在于组件最小宽度和最大宽度相比较时.相差越多,结果越明显,会看到列中有很大的缝隙.占据的宽度是组件所需要的最小的宽度
.注意第3列比第2列稍微宽一点点,这是因为第3列中的文字长度比第2列中文字要长点 .如果需要阅读布局的相关理论,可以去这里W3C recommendations for HTML table auto-layout. ColumnLayout
Eclipse Forms另外一个定制的layout是SWT RowLayout的变种.如果我们把RowLayout上的children垂直放置时--按列-并且使同列中的所有组件拥有相同的宽度,我们会由组件的宽度得到多个列.但是,最后一列显然不是被填满的--这由组件的个数决定 .如果在form中,我们会仍然看到所有组件在一列中,因为RowLayout不能够 "垂直" 包裹.如果我们用GridLayout相替代的话,列的数量由我们自己决定. 在更加复杂的forms中我们需要列的数量按情况变化.换句话来说,我们希望数字按照form的宽度来改变--有可能需要更多的列,当宽度减小时则把数字减小.而且我们希望所有列的长度象报纸布局一
样相同.这些要求都能够通过ColumnLayout来达到. 与TableWrapLayout相比,ColumnLayout更加简单.不需要复杂的设置
图片10:使用ColumnLayout的所有按列排列的段落.唯一需要你设置的就是列数的范围,默认是1到3.下面的例子演示了一个使用ColumnLayout 的有许多段落(sections)的form.初始时,只需要两列就可以放置所有段落了.如果我们把编辑器变窄一点,layout会使它们在同一列中. .layout开始是两列,但是按照空间的改变变成了一列.