swt的常用组件button ,text ,combo,list ,还有一些容器类composite ,group,这里选择几个,列写简单的用法
不写解释了,因为代码很简单,而且代码上的注释足以说明.
1,combo 和text
package com.test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

2,list、 button 、messagebox
package com.test;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;

3,group组
package com.test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

![]()
====================================================
1,简单显示,表格的式样见注释中的内容
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

}
2,加入布局
显示的效果不好,我们要加入布局,让view填充整个画面在shell.open()后加上
ok,效果达到
3,为TableViewer加上数据,光突突的样子不好看。这里是demo所以不再从数据库里边取数据了。自己构造一个List用来做数据。实际使用中也是这么使用,不过不同的是这里是随意构造的list,而显示实际使用中是从数据库取出数据构造list.
(1)构造一个people类,同时给People类提供一个构造假数据的方法getPeople()
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
}
(2)给tableViewer提供内容器(IStructuredContentPorvider)和标签器(ITableLabelProvider)
如果想一个tableviewer显示数据,那必须给它提供内容器和标签器,内容器的作用是从List(也可以是其他的集合类)中提取出一个对象(例如People对应着表格的一行,数据库的一条记录),标签器的作用是从一个对象中提取出一个字段(例如年龄,对应着表格中的一个单元格,数据库中某一列的一个值)下边是内容器和标签器的代码:
内容器:
import java.util.List;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;

}
标签器:
import java.text.SimpleDateFormat;

import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;

}
注意这里:extends LabelProvider,为什么要加这个呢? 因为如果不加这个,因为实现 ITableLabelProvider 的缘故我们还要写四个空函数,而我们本身不需要在这四个空函数中实现什么,所以让它继承自LabelProvider,就可以避免四个空函数。
(3)把标签器和内容器给tableviewer
在shell.open()前边加上这几行
//设置内容器
tableViewer.setContentProvider(new ContentProvider());
//设置标签器
tableViewer.setLabelProvider(new TableLabelProvider());
//把数据集合给tableView
tableViewer.setInput(People.getPeople());
//这样利用内容器和标签器就能从setInput得到的数据集合分解出显示表格需要的数据。这是一个典型的mvc的实现.
4,样式改变
如果想在每一列前加入一个checkbox
只需要在开始的式样中加入SWT.CHECK
好了到此一个简单的样子选择出来了,但这仅仅是开始,下边将继续介绍按列排序、过滤器、行的颜色设置、在表格上直接编辑等功能
SourceCode
=============================================
有一个功能是我们常使用的,就是在列的头上点击一下,整个表的记录按照这个列来排序,再点击一下按照这个列的反序来排序。那JFace是如何实现这个功能的呢?
在JFace中是通过一个排序器来实现的,就是ViewerSorter下边写出详细的步骤
一、定义一个sorter继承自ViewerSorter
import java.util.Date;

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;

}
二、在TableViewer上,为每一列加入事件监听器类似这样的结构
![]()
);
都加入后TestTableViewer的结果:
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

}
试一下结果是不是出来了?
好了,最后解释几点:
1,sorter中利用了jdk的compareTo来实现比较,当然你也可以根据自己的需求来实现。
2, sorter中利用了"-"符号来得到正负数字,用来表现升序、降序。
SourceCode
======================================================
前边实现了一个表格的基本功能,但这并不够好,能否为表格实现一些更好的功能呢?答案是肯定的。下边我们来加入直接编辑的功能。
一、要实现这个功能必须提供一个实现ICellModifier的类。内容如下
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.TableItem;

}
二、好了,有了这个类,下一部就是如何把它和TestTableViewer关联起来,在TestTableViewer中setInput()后加入如下内容
![]()
tableViewer.setCellModifier(modifier);
我们让名字这一列用下拉条来编辑,让性别这一列变成类似checkbox的操作,让年龄这一类变成直接输入
ok,尝试一下。
三、问题出现,如果年龄的地方我们输入一个非数字呢,所以为了安全起见,我们加入一个验证器,禁止用户输入非数字
在上边的内容下加入
Text text = (Text)cellEditor[3].getControl();
);
好了,再试试是否不能输入非整数了?解决。其实还是有些问题的,试着输入个0,呵呵。这里就需要你自己按照自己的实际需求来实现了。
但作为demo这个的目的已经达到了。
SourceCode
=======================================================
如果我们想根据某一列来过滤记录,如何实现呢?很简单,定义一个过滤器filter。这里只演示定义一个过滤器的情况。
现实中你可以定义多个灵活的过滤器,通过替换过滤器来实现各种各样的过滤。
一、过滤器代码:
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;

}
然后在testTableViewer的shell.open前加入这个过滤器
tableViewer.addFilter(new MyFilter());
好了,看一下效果
二、如果我们想凸显某一条记录,想改变一下它的颜色,如果实现呢,简单,只要几句话就可以了。
Color color = Display.getDefault().getSystemColor(SWT.COLOR_RED);
table.getItems()[table.getItemCount()-1].setBackground(color);
table.redraw();
三、这里提一下,使用tabeViewer.setUseHashlookup(true)可以在tableviewer内部为数据记录和tableItem之间的映射创建一个hash表,这样可以加快tableItem的和记录间的查找速度,注意,这条语句必须在setInput之前加入才有效。
好了,到此tableviewer的基本的东西介绍的差不多了
source下载:sourcecode
四:在现实的开发中,我们更多的是喜欢把一些简单的类用匿名类或者内部类的方式来实现。像之前例子中每个都单独一个类的情况并不多。
下边是和前边的source效果等同的source,不过是使用了匿名类和内部类。
source下载:SourceCode
=============================================
上边介绍了,tableviewer,这里介绍一下treeViewer,总的流程类似。
一、构造一个树形结构的数据出来,这里选择国家、城市、人来构造一个树形结构,代码如下:
1,定义一个接口
package model;

import java.util.List;

2,国家
package model;

import java.util.ArrayList;
import java.util.List;

3,城市
package model;

import java.util.ArrayList;
import java.util.List;

4,人
package model;

import java.util.ArrayList;
import java.util.List;

5,把这些元素组织起来
package model;

import java.util.ArrayList;
import java.util.List;

二、定义内容器和标签器
1,内容器
import java.util.List;

import model.Itree;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

}
2,标签器:
import model.Itree;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;

}
三、好了,准备工作做好了,把上边的内容利用起来就好了。
import model.Factory;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;


看看是不是已经实现了treeViewer
四、上边是简单的treeViewer,如果我们需要带checkbox的treeViewer,简单,只需要更改
final TreeViewer treeViewer = new TreeViewer(shell, SWT.BORDER|SWT.H_SCROLL);
把TreeViewer换成CheckboxTreeViewer。这就是mvc的好处了。
但现实中我们多用ContainerCheckedTreeViewer代替CheckboxTreeViewer,因为这个提供了更多的功能。
CheckboxTreeViewer是TreeViewer的子类, ContainerCheckedTreeViewer是CheckboxTreeViewer的子类,所以可以随便替换。
替换后:
final ContainerCheckedTreeViewer treeViewer = new ContainerCheckedTreeViewer(shell, SWT.BORDER|SWT.H_SCROLL);
五、treeviewer和tableviewer都介绍过了,考虑一下把两个结合起来是不是我们经常需要的情况。尝试一下吧。
SourceCode
========================================================
前边将过了TableViewer和TreeViewer再来看ListViewer就简单了,操作步骤一样,但更简单。这里只给出使用的代码
一、代码,这个实现不同于前边是分开实现(都是public 的类),这里给出的是内部类的实现方式。
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


二、注意代码的注释部分,可以直接添加和移除。
===================================================
Jface的hello World网上到处都是,但简单的Hello world能引出很多需要注意的问题.
首先大部分网上的jface helloworld如下:
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;


这个代码是可以运行的,而且运行的结果也看不出什么问题。但看不出来并不代表没有问题。下边我们来让问题显现
在createContents()函数中再加入一个Text代码变成
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;


运行,并没有看到第二个Text,为什么?
是否没有设置text的Bounds?好设置一下
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;


效果依旧,那是为什么呢?
这是因为在createContents()方法中直接使用了参数中的parent,造成了布局(layout)的混乱,在只有一个的text的情况下看不出来,现在就看出来了。
解决办法:再构造一个composite,在我们平时使用的时候记得一定要构造一个自己的composite,设置自己的布局,不要直接使用参数中的composite
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;


}