SWT遵循操作系统平台直接支持的线程模型。应用程序在它的主线程中运行事件循环,并直接从此线程中调度事件,该线程是应用程序的“UI线程”。事实上UI线程既是创建显示的线程,也是运行事件循环和创建窗口的线程。由于所有事件都是从应用程序的用户界面线程中触发的,因此,处理事件的应用程序代码可以自由地访问窗口组件,且不需要任何特殊技术就可以进行图形调用。
main方法代码如下:
while(!shell.isDisposed()){ if(!display.readAndDispath()){ display.sleep(); } }
在Java swt gui程序的main方法中,一旦窗口(shell)创建并处于打开状态,应用程序就会读取和调度操作系统队列中的事件,直到窗口被清除。
Display对象负责SWT和操作系统之间的联系,将SWT/JFace的各种调用转化为系统的底层调用,控制操作系统为SWT分配的资源,获得操作系统的有关信息。在Display的事件循环中,同时处理着系统队列和自定义队列的事件。display.readAndDispatch的执行流程是:首先从系统事件队列中读取消息,如果读到该程序的事件,就将它发送到窗口去处理;如果该程序没有系统事件,则处理自定义事件队列中的事件,处理完该事件返回true。如果两个队列中的都没有事件返回false,则Display调用sleep方法,显示线程进入睡眠状态,以使其他线程有机会运行。若事件队列中有新的事件传来,则UI线程会被唤醒并恢复事件循环过程。
1.1 事件处理
所谓事件,就是发送给GUI系统的消息,该消息通知GUI系统某种事情已经发生,要求做出响应。
Java中的事件使用对象描述-事件的发生源、事件的类别、事件发生前和发生后组件状态的变化等。
根据事件发生的来源可分为以下几种:
1 计算机输入输出设备产生的中断事件,如鼠标键盘与GUI系统的交互。一般是原生底层事件,需要进一步处理,出发更高层次逻辑事件。
2 GUI系统出发的逻辑事件。原始事件经过组件的处理后派发的高级事件比如单机Button候船省的SelectionEvent e等
3 应用程序创发的事件。有两种方式:
1)通过将事件添加到系统事件队列进行派发。Swing中通过repaint、invokeLater等方法添加事件。这种触发机制实质上是调度,触发事件的线程和事件派发线程可以不是同一个线程。事件被添加到队列后触发过程结束,后要在事件派发线程上等待执行事件的处理代码。
2)通过调用组件的派发方法(swing中是fireEventXxx)触发。使用这种方法,事件对象不会发送到系统事件队列,而是直接传递给事件处理方法进行处理。它的触发机制实质上是方法调用。这种事件触发方式要求事件处理线程必须同时是事件派发线程。
1.2 事件处理模型
用户在事件源上做了操作(如在按钮上点击)。GUI平台操作系统生成GUI事件,并添加到事件队列,同时Java运行环境产生特定事件对象(SelectionEvent e).Java SWT GUI程序的事件循环按以下步骤处理。
1 Display对象执行readAnddispatch()方法,用msg接受事件对象。
2 发现相关事件,将事件放松到顶级Shell对象,决定哪些组件应该接受事件。
3 Shell发送时间到用户操作的那个组件---事件源,并把事件发生的信息传递给事件监听器。
4 事件监听器根据具体动作调用其他方法处理用户的操作。
1.3 SWT事件处理机制
两种:无类型的事件处理机制、有类型的事件处理机制
1.无类型处理机制,相关事件发生时,监听器的handleEvent()方法被调用。SWT的实现使用了这种机制,很多向导页的实现也是,但应用程序很少用。
2.有类型的事件处理机制,只对特定类型事件进行监听。XxxEvent,描述GUI的Xxx事件。XxxListener,事件处理方法所在类。
1.4事件监听器的两种实现方式
实现接口,继承适配器
1.5常用事件监听器
1 鼠标事件
MouseListener 按下、抬起、双击
MouseMoveListener 移动事件
MouseTrackListener 进入退出悬停事件
2 键盘事件
KeyListener 键盘事件
3 焦点事件
FocusListener 焦点失去或获得
4 组件控制事件
ControlListener 组件被移动或大小被改变
5 选择事件
SelectionListener 单机组件操做的响应方法。如在按钮上点击,或者当按钮获取焦点时回车。
6 组件专用事件监听器
文本框和组合框的ModifyEvent和ModifyListener等等
2.1 布局设计
1.填充式布局FillLayout
2.行列式布局RowLayout
行列式布局按行或列包含在容器的组件。但是与FillLayout不同,它不会强制所有的组件采用统一大小,超出一行列会自动换行。容器中的每个组件可以使用LayoutData进行个性化布局设置。
type:横向还是纵向,默认HORIZANTAL横向
wrap:换行还是不换行,默认为true换行
pack:首选大小还是与最大组件大小一致,默认为true首选大小
justify:紧挨着还是分散开来,默认false不分开
fill:首选尺寸还是宽或高一致 默认false首选尺寸
marginleft marginright margintop marginbottom spaction 默认为3
3. 网格式布局GridLayout
numColumns 设置网格的列数 默认列数为1
makeColumnsEuqalWidth 强制设置所有列宽度相同,默认为false
marginWidth marginHeight horizontalSpacing verticalSpacing
LayoutData属性:
horizontalAlignment 和 verticalAligment 对齐方式
horizontallndent 和 verticalIndent (小范围)缩进
horizontalSpan 和 verticalSpan 占用行数和列数 默认为1
grabExcessHorizontalSpace 和 grabExcessVerticalSpace 抢占容器空白位置(fill放大自身,其它保持位置)
widthHint 和 heightHint 以像素为单位指定一个组件的大小
4. 表格式布局FormLayout
灵活、精确 相对位置或者绝对位置来定位 像素或者百分比来当作单位(略)
5.堆栈式布局StackLayout
设置容器内所有组件的大小位置相同,然后层叠在一起。
marginHeight 上下边距
marginWidth 左右边距
6.流式布局 FlowLayout(从左到右从上到下)
7.盒式布局 BoxLayout(坐标布局)
8.边框式布局 BorderLayout(上北下南左西右东)
3. 容器的使用
6.1 面板容器
面板(Composite)是SWT中最常用的容器,创建面板容器中设置适当的布局,向其中加入其他子组件,从而作为页面布局工具使用。
6.2 分组框