SWT/JFace学习之布局管理
1. 布局管理器(Layout),布局管理数据(LayoutData),不同容器之间的布局
layoutData:控制布局属性的数据
layout:布局管理方式
只有像composite这种属于容器的才有setLayout方法,
一个容器控件的setLayout设置的是它对它所包含的子控件的布局管理方式。
而一个控件(容器或者非容器控件)setLayoutData设置的是控件本身在包含它的布局管理器的中的布局属性,即setLayout是容器对它包含的子控件的布局方式,而控件的setLayoutData是设置自己在上一层容器中的布局定位属性,
它们不是对应的,之前我的理解是错误的:一个control的设置什么Layout,它的setLayoutdata也得设置成对应的,要不然就会出现像GridDatacannotcasttoFormData这种异常。
正确的理解是,如果一个容器设置了什么layout,那么它的子控件(包括composite等容器)的setLayoutData得设置成对应的Data数据
如果一个容器指定了一个布局管理方式,那么它包含的其它容器可以定义自己的容器管理,只要它们的layout与layoutdata满足上面说的即可。如父容器使用的是RowLayout,它包含的子容器可以使用非RowLayou来管理自己的布局,如GridLayout,但该子容器的layoutdata得是RowData,因为包含它的父容器使用的是RowLayout,它作为其中的一个元素,当然也得使用RowData来定义自己如何布局
之前我的理解也是错误的认为父控件使用了什么管理器,子控件也只能使用相应的管理器
这些错误的理解都是一开始就使用可视化工具来进行设置,却对最基本的swt的了解忽略了
,可视化工具开发快,但代码的质量和一些结构性,耦合性及重用性还得进行重构,重构后可视化工具就不能很好的处理了(eclipse上的可视化好像都有这种问题,netbean要好点,因为它生成的代码本身结构就要好点),就出现了各种问题
SWT提供的布局管理器
布局都有其相应的数据(Layout Data),可以通过Control.setLayoutData()方法来进行关联。以下是一些布局类及其显示效果:FillLayout:让所有子组件等大小的”填满”整个面板空间。FillLayout是最简单的一个布局类,它将所有窗口组件放置到一行或一列中,并强制他们的大小也相等。FillLayout不能外覆(wrap),也不能定制边框和距离。很显然这样的限制让这个布局类最适合作类似于计算器面板的布局,或者为Taskbar和Toolbar上面的按钮作布局使用。
RowLayout:类似于AWT中的FlowLayout,让所有组件按行排列,一行排不下就放到下一行。RowLayout比FillLayout用得更广泛一些,原因很简单,就是RowLayout支持FillLayout所部支持的功能,例如能够外覆,能够修改边框和间距等等。另外,每一个位于RowLayout中的窗口组件都可以通过设定一个RowData类来指定其在RowLayout中的宽度和高度。
GridLayout: GridLayout是3个标准布局类中最有用的,但同时也是最复杂的–没办法,强大的功能必定伴随着一定程度的复杂性。通过GridLayout,一个Composite的子窗口组件被放置在一个网格(Grid)之中。GridLayout有很多配置字段,并且和RowLayout一样,每一个布局于其中的窗口组件都可以有一个与之相关联的布局数据类,称为GridData。GridLayout的强大功能是通过对于每一个窗口组件的GridData的灵活控制来实现的。鉴于GridLayout的复杂性(原本我就怀疑它根本就不是为手工书写代码而设计的),我并不建议各位直接手动书写GridData,最好借助可视化的工具(如VI)来帮助我们完成用GridLayout进行的界面设计。这样我们只需要书写少量控制代码,就可以获得复杂的界面布局了。
FormLayout: 跟GridLayout一样很强大,而且布局定义非常自由,可以自由定义每个控件的位置,如定义控件的重叠效果,grid控件只能定义在一个网格中
StackLayout:几乎完全等同于CardLayout的功能。
自适应问题
一般情况下不要用setSize或者setBound(x,y,width,height)等方法把控件的大小写死(特别是负责定位布局的容器,对于非容器控件有时需要设置它们的大小的),因为这样界面的自适应不好,分辨率改变或者屏幕的大小不一样时,可能造成界面的变形或者看不见等浏览问题。
应该使用好容器,SWT的最顶层容器是全部填充的(一个viewer中最顶层的容器),它解决了不同分辨率一屏幕下的自适应问题,我们要做的就是在这个容器下定义好布局管理,个人觉得最好都使用相对的布局定位,这样可以更好的自适应,不要把定位属性都写死了,特别是把location这些内容通过计算得出这种做法是最不可取的,因为窗口的大小改变或者滚动条的等原因都使得这种计算出来的结果不正确
SWT与操作系统的集成
swt是直接与操作系统集成的,而不是像awt/swing那样建立在jvm上,所以有种说法是swt是原生窗口系统,awt/swing是仿生窗口系统。这点在使用eclipse与zendstudio5就有很明显的比较,eclipse的反应很快,zendstudio5是使用swing开发的,刚打开时感觉不是很明显,但程序运行的时间长后,从其它程序切换回来后会有很长的一段时间zendstudio界面是灰的,什么也没有,然后整个界面才显示出来
swt的org.eclipse.swt.internal.win32.OS等几个估计就是最底层与win32集成的地方里面的方法都是native的,而org.eclipse.swt.win32.win32.x86_XXX包里有几个dll文件,估计是这些native方法javah出的.h及实现文件吧
其它
Display
这是一个顶层容器组件,类似于Container或Component的功能,它主要负责与底层的窗口系统之间的连接。在具体含义上,它代表”屏幕”。
一个Display可以包含多个Shell(也是容器组件,下面会介绍到)。
通常情况下,一个应用程序只含一个Display,即Display通常是一个单例组件(Singleton)。
Shell
它表示位于”屏幕”上面的”窗口”,是Composite组件和Control组件构成的组件树的根。