【插件开发】—— 10 JFace开发详解
前文回顾:
1 插件学习篇
4 SWT编程须知
7 SWT布局详解
9 编辑器代码着色
前几篇讲过SWT的使用,但是SWT是基本的小控件,只能针对使用简单的数据类型,比如字符串,数字等等。但是遇到了复杂的类,该怎么办呢?
不要担心!这里就可以使用JFace了,它是对SWT的封装,可以应用于复杂的数据类型。
下面的介绍中有时候说控件,有时候说视图,原因就是这个JFace通常用于某个视图中,但是它其实就是一个复杂的组合控件而已,只不过需要我们额外的去设定内容与复杂类的内容匹配。因此如果想使用复杂的数据类型,必然要与JFace提供的控件进行兼容,就涉及到两个主要的函数:setContentProvider() 以及 setLabelProvider()。这两个函数下面会进行详细的介绍:
setContentProvider() 内容提供者
这个函数为JFace的控件提供内容,总的来说一共有一下几种:
ListViewer列表视图 TabelViewer表格视图 TreeViewer树形视图 TextViewer文本视图
除了最后一种比较特殊,不需压指定内容提供者,其他的三个JFace视图都需要设置内容提供者,以便设定关联的内容。
setLabelProvider()标签提供者
这个函数设置了标签提供者,用于JFace的控件视图现实内容,一般来说都有两个函数:
getColumnImage()和getColumnText(),一个用于设定标签上现实的图片,一个用于设定现实的内容
那么下面就看一下不同的JFace视图,这两个函数使用的差异。
ListViewer
这个列表视图,属于最简单的视图了,这里我们创建一个复杂点的元素
1 class Person{ 2 private int id; 3 private String name; 4 private int age; 5 private String address; 6 public int getId() { 7 return id; 8 } 9 public void setId(int id) { 10 this.id = id; 11 } 12 public String getName() { 13 return name; 14 } 15 public void setName(String name) { 16 this.name = name; 17 } 18 public int getAge() { 19 return age; 20 } 21 public void setAge(int age) { 22 this.age = age; 23 } 24 public String getAddress() { 25 return address; 26 } 27 public void setAddress(String address) { 28 this.address = address; 29 } 30 public String toString() { 31 return name; 32 } 33 }
当我们从扩展点创建一个视图,并打开它的实现类时,插件为我们自动添加好了接口,里面有三个直接生成的函数
public class ListViewerTest extends ViewPart { public ListViewerTest() { } public void createPartControl(Composite parent) { } public void setFocus() { } }
此时,我们需要扩展createPartControl,在这里面创建一个view,并在其中添加 内容提供者函数,以及标签提供者函数。
viewer = new ListViewer(parent, SWT.SINGLE); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setSorter(new MySorter()); viewer.setInput(getSite());
通常来说,都会有上面的五句话
第一行:创建了一个ListViewer的视图
第二行:设置它的内容提供者
第三行:设置它的标签提供者
第四行:设置排序规则
第五行:设置输入,这里面我们的输入由内容提供者提供,因此这里就直接设置参数为getSite()(可以理解为一个字符串,这个地方随便写都行,但是一定要有这个函数,空串都可以)就可以了。
下面看一下这几个函数的实现:
class ViewContentProvider implements IStructuredContentProvider{ public Object[] getElements(Object inputElement) { Person[] persons = new Person[3]; persons[0] = new Person(); persons[0].setId(001); persons[0].setName("xingoo"); persons[0].setAge(25); persons[0].setAddress("ChangChun"); persons[1] = new Person(); persons[1].setId(002); persons[1].setName("halo"); persons[1].setAge(27); persons[1].setAddress("ShenYang"); persons[2] = new Person(); persons[2].setId(003); persons[2].setName("haha"); persons[2].setAge(25); persons[2].setAddress("DaLian"); return persons; } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } class ViewLabelProvider extends LabelProvider{ public Image getColumnImage(Object element) { return null; } public String getColumnText(Object element) { return getText(element); } } class MySorter extends ViewerSorter{ public int compare(Viewer viewer,Object ob1,Object ob2){ return ((Person)ob1).getId() - ((Person)ob2).getId(); } }
对于内容提供者来说,最重要的一个方法就是getElements,因为视图上现实的数据,都要从这个方法获得。
下面看一下对应的全部代码
1 package testpreference.views; 2 3 import org.eclipse.jface.viewers.DoubleClickEvent; 4 import org.eclipse.jface.viewers.IDoubleClickListener; 5 import org.eclipse.jface.viewers.ISelectionChangedListener; 6 import org.eclipse.jface.viewers.IStructuredContentProvider; 7 import org.eclipse.jface.viewers.IStructuredSelection; 8 import org.eclipse.jface.viewers.LabelProvider; 9 import org.eclipse.jface.viewers.ListViewer; 10 import org.eclipse.jface.viewers.SelectionChangedEvent; 11 import org.eclipse.jface.viewers.Viewer; 12 import org.eclipse.jface.viewers.ViewerSorter; 13 import org.eclipse.swt.SWT; 14 import org.eclipse.swt.graphics.Image; 15 import org.eclipse.swt.widgets.Composite; 16 import org.eclipse.ui.part.ViewPart; 17 class Person{ 18 private int id; 19 private String name; 20 private int age; 21 private String address; 22 public int getId() { 23 return id; 24 } 25 public void setId(int id) { 26 this.id = id; 27 } 28 public String getName() { 29 return name; 30 } 31 public void setName(String name) { 32 this.name = name; 33 } 34 public int getAge() { 35 return age; 36 } 37 public void setAge(int age) { 38 this.age = age; 39 } 40 public String getAddress() { 41 return address; 42 } 43 public void setAddress(String address) { 44 this.address = address; 45 } 46 public String toString() { 47 return name; 48 } 49 } 50 51 52 public class ListViewerTest extends ViewPart { 53 public static final String ID = "testpreference.views.ListViewerTest"; 54 private ListViewer viewer; 55 56 public ListViewerTest() { 57 58 } 59 60 public void createPartControl(Composite parent) { 61 viewer = new ListViewer(parent, SWT.SINGLE); 62 viewer.setContentProvider(new ViewContentProvider()); 63 viewer.setLabelProvider(new ViewLabelProvider()); 64 viewer.setSorter(new MySorter()); 65 viewer.setInput(getSite()); 66 67 viewer.addSelectionChangedListener( new ISelectionChangedListener() { 68 public void selectionChanged(SelectionChangedEvent event) { 69 IStructuredSelection selection = (IStructuredSelection)event.getSelection(); 70 System.out.println("Now selecting "+selection.getFirstElement().toString()); 71 } 72 }); 73 74 viewer.addDoubleClickListener( new IDoubleClickListener() { 75 public void doubleClick(DoubleClickEvent event) { 76 IStructuredSelection selection = (IStructuredSelection)event.getSelection(); 77 System.out.println("Double clicking "+selection.getFirstElement().toString()); 78 } 79 }); 80 } 81 82 public void setFocus() { 83 84 } 85 class ViewContentProvider implements IStructuredContentProvider{ 86 public Object[] getElements(Object inputElement) { 87 88 Person[] persons = new Person[3]; 89 persons[0] = new Person(); 90 persons[0].setId(001); 91 persons[0].setName("xingoo"); 92 persons[0].setAge(25); 93 persons[0].setAddress("ChangChun"); 94 95 persons[1] = new Person(); 96 persons[1].setId(002); 97 persons[1].setName("halo"); 98 persons[1].setAge(27); 99 persons[1].setAddress("ShenYang"); 100 101 persons[2] = new Person(); 102 persons[2].setId(003); 103 persons[2].setName("haha"); 104 persons[2].setAge(25); 105 persons[2].setAddress("DaLian"); 106 107 return persons; 108 } 109 public void dispose() { 110 } 111 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 112 } 113 } 114 class ViewLabelProvider extends LabelProvider{ 115 public Image getColumnImage(Object element) { 116 return null; 117 } 118 public String getColumnText(Object element) { 119 return getText(element); 120 } 121 } 122 class MySorter extends ViewerSorter{ 123 public int compare(Viewer viewer,Object ob1,Object ob2){ 124 return ((Person)ob1).getId() - ((Person)ob2).getId(); 125 } 126 } 127 }
tableViewer
这个对于上面的Listviewer来说,标签提供者方面复杂了一些
首先,创建视图时,需要定义Table的样式
1 viewer = new TableViewer(parent,SWT.SINGLE|SWT.FULL_SELECTION); 2 Table table = viewer.getTable(); 3 table.setHeaderVisible(true); 4 table.setLinesVisible(true); 5 6 String[] columnNames = new String[]{"id","name","age","address"}; 7 int[] columnWidths = new int[]{100,100,100,100}; 8 int[] columnAlignments = new int[]{SWT.LEFT,SWT.LEFT,SWT.LEFT,SWT.LEFT}; 9 for(int i=0;i<columnNames.length;i++){ 10 TableColumn tableColumn = new TableColumn(table,columnAlignments[i]); 11 tableColumn.setText(columnNames[i]); 12 tableColumn.setWidth(columnWidths[i]); 13 } 14 15 viewer.setContentProvider(new ViewContentProvider()); 16 viewer.setLabelProvider(new ViewLabelProvider()); 17 viewer.setSorter(new MySorter()); 18 viewer.setInput(getSite());
对于标签提供者函数来说,稍微麻烦一点,需要根据index指定每一列显示的内容
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider{ public Image getColumnImage(Object element,int index) { return null; } public String getColumnText(Object element,int index) { Person person = (Person)element; switch(index){ case 0: return person.getId()+""; case 1: return person.getName(); case 2: return person.getAge()+""; case 3: return person.getAddress(); default: return "unknown"+index; } } }
全部代码及运行结果
1 package testpreference.views; 2 3 import org.eclipse.jface.viewers.IStructuredContentProvider; 4 import org.eclipse.jface.viewers.ITableLabelProvider; 5 import org.eclipse.jface.viewers.LabelProvider; 6 import org.eclipse.jface.viewers.TableViewer; 7 import org.eclipse.jface.viewers.Viewer; 8 import org.eclipse.jface.viewers.ViewerSorter; 9 import org.eclipse.swt.SWT; 10 import org.eclipse.swt.graphics.Image; 11 import org.eclipse.swt.widgets.Composite; 12 import org.eclipse.swt.widgets.Table; 13 import org.eclipse.swt.widgets.TableColumn; 14 import org.eclipse.ui.part.ViewPart; 15 16 public class TableViewerTest extends ViewPart { 17 public static final String ID = "testpreference.views.TableViewerTest"; 18 private TableViewer viewer; 19 public TableViewerTest() { 20 // TODO Auto-generated constructor stub 21 } 22 23 public void createPartControl(Composite parent) { 24 viewer = new TableViewer(parent,SWT.SINGLE|SWT.FULL_SELECTION); 25 Table table = viewer.getTable(); 26 table.setHeaderVisible(true); 27 table.setLinesVisible(true); 28 29 String[] columnNames = new String[]{"id","name","age","address"}; 30 int[] columnWidths = new int[]{100,100,100,100}; 31 int[] columnAlignments = new int[]{SWT.LEFT,SWT.LEFT,SWT.LEFT,SWT.LEFT}; 32 for(int i=0;i<columnNames.length;i++){ 33 TableColumn tableColumn = new TableColumn(table,columnAlignments[i]); 34 tableColumn.setText(columnNames[i]); 35 tableColumn.setWidth(columnWidths[i]); 36 } 37 38 viewer.setContentProvider(new ViewContentProvider()); 39 viewer.setLabelProvider(new ViewLabelProvider()); 40 viewer.setSorter(new MySorter()); 41 viewer.setInput(getSite()); 42 } 43 44 public void setFocus() { 45 // TODO Auto-generated method stub 46 47 } 48 class ViewContentProvider implements IStructuredContentProvider { 49 public Object[] getElements(Object inputElement) { 50 51 Person[] persons = new Person[3]; 52 persons[0] = new Person(); 53 persons[0].setId(001); 54 persons[0].setName("xingoo"); 55 persons[0].setAge(25); 56 persons[0].setAddress("ChangChun"); 57 58 persons[1] = new Person(); 59 persons[1].setId(002); 60 persons[1].setName("halo"); 61 persons[1].setAge(27); 62 persons[1].setAddress("ShenYang"); 63 64 persons[2] = new Person(); 65 persons[2].setId(003); 66 persons[2].setName("haha"); 67 persons[2].setAge(25); 68 persons[2].setAddress("DaLian"); 69 70 return persons; 71 } 72 public void dispose() { 73 } 74 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 75 } 76 } 77 class ViewLabelProvider extends LabelProvider implements ITableLabelProvider{ 78 public Image getColumnImage(Object element,int index) { 79 return null; 80 } 81 public String getColumnText(Object element,int index) { 82 Person person = (Person)element; 83 switch(index){ 84 case 0: 85 return person.getId()+""; 86 case 1: 87 return person.getName(); 88 case 2: 89 return person.getAge()+""; 90 case 3: 91 return person.getAddress(); 92 default: 93 return "unknown"+index; 94 } 95 } 96 } 97 class MySorter extends ViewerSorter{ 98 public int compare(Viewer viewer,Object ob1,Object ob2){ 99 return ((Person)ob1).getId() - ((Person)ob2).getId(); 100 } 101 } 102 103 }
TreeViewer
这个视图相比前面的这个复杂在它的内容提供者函数,我们需要让他的ContentProvider函数继承ITreeContentProvider接口,需要实现下面几个方法:
getChildren();获取节点的孩子节点。
getParent();获取节点的父节点
hasChildren();判断是否有孩子节点
getElements();获取全部的节点
下面看一下示例的代码
1 class ViewContentProvider extends ArrayContentProvider implements ITreeContentProvider{ 2 3 public Object[] getChildren(Object parentElement) { 4 TreePerson person = (TreePerson)parentElement; 5 return person.getChildren().toArray(); 6 } 7 8 public Object getParent(Object element) { 9 TreePerson person = (TreePerson)element; 10 return person.getParent(); 11 } 12 13 public boolean hasChildren(Object element) { 14 TreePerson person = (TreePerson)element; 15 return person.getChildren().size()>0?true:false; 16 } 17 18 public Object[] getElements(Object inputElement) { 19 TreePerson[] persons = new TreePerson[3]; 20 persons[0] = new TreePerson(); 21 persons[0].setId(001); 22 persons[0].setName("xingoo"); 23 persons[0].setAge(25); 24 persons[0].setAddress("ChangChun"); 25 26 persons[1] = new TreePerson(); 27 persons[1].setId(002); 28 persons[1].setName("halo"); 29 persons[1].setAge(27); 30 persons[1].setAddress("ShenYang"); 31 32 persons[2] = new TreePerson(); 33 persons[2].setId(003); 34 persons[2].setName("haha"); 35 persons[2].setAge(25); 36 persons[2].setAddress("DaLian"); 37 38 persons[0].getChildren().add(persons[1]); 39 persons[0].getChildren().add(persons[2]); 40 persons[1].setParent(persons[0]); 41 persons[2].setParent(persons[0]); 42 43 return persons; 44 } 45 46 }
而他的标签提供者跟ListViewer的差不多,仅仅需要提供一个简单的名称就可以了。
class ViewLabelProvider extends LabelProvider{ public Image getColumnImage(Object element) { return null; } public String getColumnText(Object element) { return ((TreePerson)element).toString(); } }
全部代码以及运行结果
1 package testpreference.views; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.eclipse.jface.viewers.ArrayContentProvider; 7 import org.eclipse.jface.viewers.ITreeContentProvider; 8 import org.eclipse.jface.viewers.LabelProvider; 9 import org.eclipse.jface.viewers.TreeViewer; 10 import org.eclipse.jface.viewers.Viewer; 11 import org.eclipse.jface.viewers.ViewerSorter; 12 import org.eclipse.swt.SWT; 13 import org.eclipse.swt.graphics.Image; 14 import org.eclipse.swt.widgets.Composite; 15 import org.eclipse.ui.part.ViewPart; 16 class TreePerson{ 17 private int id; 18 private String name; 19 private int age; 20 private String address; 21 private List<TreePerson> children; 22 private TreePerson parent = null; 23 24 public TreePerson() { 25 children = new ArrayList(); 26 } 27 public List<TreePerson> getChildren() { 28 return children; 29 } 30 public void setChildren(List<TreePerson> children) { 31 this.children = children; 32 } 33 public TreePerson getParent() { 34 return parent; 35 } 36 public void setParent(TreePerson parent) { 37 this.parent = parent; 38 } 39 public int getId() { 40 return id; 41 } 42 public void setId(int id) { 43 this.id = id; 44 } 45 public String getName() { 46 return name; 47 } 48 public void setName(String name) { 49 this.name = name; 50 } 51 public int getAge() { 52 return age; 53 } 54 public void setAge(int age) { 55 this.age = age; 56 } 57 public String getAddress() { 58 return address; 59 } 60 public void setAddress(String address) { 61 this.address = address; 62 } 63 public String toString() { 64 return name; 65 } 66 } 67 public class TreeViewerTest extends ViewPart { 68 public static final String ID = "testpreference.views.TreeViewerTest"; 69 private TreeViewer viewer; 70 public TreeViewerTest() { 71 // TODO Auto-generated constructor stub 72 } 73 74 public void createPartControl(Composite parent) { 75 viewer = new TreeViewer(parent,SWT.SINGLE); 76 viewer.setLabelProvider(new ViewLabelProvider()); 77 viewer.setContentProvider(new ViewContentProvider()); 78 viewer.setSorter(new MySorter()); 79 viewer.setInput(getSite()); 80 } 81 82 public void setFocus() { 83 // TODO Auto-generated method stub 84 85 } 86 class ViewContentProvider extends ArrayContentProvider implements ITreeContentProvider{ 87 88 public Object[] getChildren(Object parentElement) { 89 TreePerson person = (TreePerson)parentElement; 90 return person.getChildren().toArray(); 91 } 92 93 public Object getParent(Object element) { 94 TreePerson person = (TreePerson)element; 95 return person.getParent(); 96 } 97 98 public boolean hasChildren(Object element) { 99 TreePerson person = (TreePerson)element; 100 return person.getChildren().size()>0?true:false; 101 } 102 103 public Object[] getElements(Object inputElement) { 104 TreePerson[] persons = new TreePerson[3]; 105 persons[0] = new TreePerson(); 106 persons[0].setId(001); 107 persons[0].setName("xingoo"); 108 persons[0].setAge(25); 109 persons[0].setAddress("ChangChun"); 110 111 persons[1] = new TreePerson(); 112 persons[1].setId(002); 113 persons[1].setName("halo"); 114 persons[1].setAge(27); 115 persons[1].setAddress("ShenYang"); 116 117 persons[2] = new TreePerson(); 118 persons[2].setId(003); 119 persons[2].setName("haha"); 120 persons[2].setAge(25); 121 persons[2].setAddress("DaLian"); 122 123 persons[0].getChildren().add(persons[1]); 124 persons[0].getChildren().add(persons[2]); 125 persons[1].setParent(persons[0]); 126 persons[2].setParent(persons[0]); 127 128 return persons; 129 } 130 131 } 132 class ViewLabelProvider extends LabelProvider{ 133 public Image getColumnImage(Object element) { 134 return null; 135 } 136 public String getColumnText(Object element) { 137 return ((TreePerson)element).toString(); 138 } 139 } 140 class MySorter extends ViewerSorter{ 141 public int compare(Viewer viewer,Object ob1,Object ob2){ 142 return ((TreePerson)ob1).getId() - ((TreePerson)ob2).getId(); 143 } 144 } 145 }
TextViewer
这个前一篇的源码编辑器上有讲解过,是一种可以编辑的Text文本,它可以设定特定复杂的样式,这里就看一个简单的例子
1 viewer = new TextViewer(parent,SWT.MULTI | SWT.V_SCROLL); 2 String str = "this is test \n this is test"; 3 Document document = new Document(str); 4 viewer.setDocument(document); 5 6 TextPresentation style = new TextPresentation(); 7 style.addStyleRange(new StyleRange(0,12,null,null,SWT.BOLD)); 8 viewer.changeTextPresentation(style, true); 9 10 viewer.setInput(getSite());
全部代码以及运行结果
1 package testpreference.views; 2 3 import org.eclipse.jface.text.Document; 4 import org.eclipse.jface.text.TextPresentation; 5 import org.eclipse.jface.text.TextViewer; 6 import org.eclipse.jface.viewers.TreeViewer; 7 import org.eclipse.swt.SWT; 8 import org.eclipse.swt.custom.StyleRange; 9 import org.eclipse.swt.graphics.Color; 10 import org.eclipse.swt.widgets.Composite; 11 import org.eclipse.ui.part.ViewPart; 12 13 import testpreference.views.TreeViewerTest.MySorter; 14 import testpreference.views.TreeViewerTest.ViewContentProvider; 15 import testpreference.views.TreeViewerTest.ViewLabelProvider; 16 17 public class TextViewerTest extends ViewPart { 18 public static final String ID = "testpreference.views.TreeViewerTest"; 19 private TextViewer viewer; 20 21 public TextViewerTest() { 22 // TODO Auto-generated constructor stub 23 } 24 25 public void createPartControl(Composite parent) { 26 viewer = new TextViewer(parent,SWT.MULTI | SWT.V_SCROLL); 27 String str = "this is test \n this is test"; 28 Document document = new Document(str); 29 viewer.setDocument(document); 30 31 TextPresentation style = new TextPresentation(); 32 style.addStyleRange(new StyleRange(0,12,null,null,SWT.BOLD)); 33 viewer.changeTextPresentation(style, true); 34 35 viewer.setInput(getSite()); 36 } 37 38 public void setFocus() { 39 // TODO Auto-generated method stub 40 41 } 42 43 }