jface databinding:label provider 实现多列表格(Table)数据绑定的两个途径
来源:互联网 发布:网络知名小说家排行榜 编辑:程序博客网 时间:2024/05/14 01:59
显示需求
如下图,希望将一组拥有两个字段的表与两列的table绑定在一起,实现自动显示。
在jface viewer中label provider用于提供数据对象到视图对象(viewer)显示内容的数据映射关系。也就是实现将数据模型中的不同字段的内容显示为viewer(如表格Table组件)中的文字或图像。
如下图IBaseLabelProvider是所有label provider的顶层抽象接口
实现上述这个需求,就是要找到合适的label provider。对于TableViewer,需要为每一列数据都要有对应文本,所以其适用的label provider是ITableLabelProvider接口实现。
ViewSupport
如果这两个字段的数据对象是有getter方法(不一定要求有setter方法),而且字段的类型都有合适的toString()方法将变量转为字符串,那么事情就变得简单:用ViewSupport就能很方便的实现绑定。
ViewSupport.bind方法会自动为提供ITableLabelProvider对象并准确实现数据对象的字段到表格中列的关系映射。
下面是ViewerSupport.bind(StructuredViewer viewer, IObservableList input, IValueProperty… labelProperties) 方法的实现代码
public static void bind(StructuredViewer viewer, IObservableList input, IValueProperty... labelProperties) { ObservableListContentProvider contentProvider = new ObservableListContentProvider(); if (viewer.getInput() != null) viewer.setInput(null); viewer.setContentProvider(contentProvider); // 创建ObservableMapLabelProvider对象作为label provider viewer.setLabelProvider(new ObservableMapLabelProvider(Properties .observeEach(contentProvider.getKnownElements(), labelProperties))); if (input != null) viewer.setInput(input); }
核心实现代码,一行代码就搞定绑定
TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION); table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn tblclmnId = new TableColumn(table, SWT.NONE); tblclmnId.setWidth(100); tblclmnId.setText("ID"); TableColumn tblclmnName = new TableColumn(table, SWT.NONE); tblclmnName.setWidth(100); tblclmnName.setText("Name"); // 这里使用org.javatuples.Pair作为数据对象元素的类 // org.javatuples.Pair有getValue0,getValue1方法用于分别获取两个成员变量 IObservableList<Pair<Integer,String>> input=createInput();// 创建ObservableList作为输入 // PojoProperties.values方法生成指定字段的IBeanValueProperty对象 ViewerSupport.bind(tableViewer, input, PojoProperties. values(new String[] { "value0", "value1"}));
完整测试代码
以下是WindowBuilder生成的测试代码。
注意需要javatuples的jar包支持
TestTableProvider.java
package testwb;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import org.eclipse.core.databinding.beans.PojoProperties;import org.eclipse.core.databinding.observable.Realm;import org.eclipse.core.databinding.observable.list.IObservableList;import org.eclipse.core.databinding.property.Properties;import org.eclipse.jface.databinding.swt.DisplayRealm;import org.eclipse.jface.databinding.viewers.ViewerSupport;import org.eclipse.jface.dialogs.Dialog;import org.eclipse.jface.dialogs.IDialogConstants;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Control;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.layout.FillLayout;import org.eclipse.swt.SWT;import org.eclipse.swt.widgets.Table;import org.eclipse.swt.widgets.TableColumn;import org.javatuples.Pair;import org.eclipse.jface.viewers.TableViewer;public class TestTableProvider extends Dialog { private Table table; /** * Create the dialog. * @param parentShell */ public TestTableProvider(Shell parentShell) { super(parentShell); } /** * Create contents of the dialog. * @param parent */ @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(new FillLayout(SWT.HORIZONTAL)); TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION); table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn tblclmnId = new TableColumn(table, SWT.NONE); tblclmnId.setWidth(100); tblclmnId.setText("ID"); TableColumn tblclmnName = new TableColumn(table, SWT.NONE); tblclmnName.setWidth(100); tblclmnName.setText("Name"); ViewerSupport.bind(tableViewer, createInput(), PojoProperties. values(new String[] { "value0", "value1"})); return container; } /** * Create contents of the button bar. * @param parent */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } @Override protected void configureShell(Shell newShell) { newShell.setText("数据标签"); super.configureShell(newShell); } private IObservableList<Pair<Integer,String>> createInput(){ List<String> names=Arrays.asList("face","car","bus"); ArrayList<Pair<Integer,String>> list = new ArrayList<Pair<Integer,String>>(); for(int i=0;i<names.size();++i){ list.add(Pair.with(Integer.valueOf(i),names.get(i))); } return Properties.<Pair<Integer,String>>selfList(Pair.class).observe(list); } public static void showTable(Shell shell){ Display display = null==shell?Display.getDefault():shell.getDisplay(); Realm.runWithDefault(DisplayRealm.getRealm(display), new Runnable() { public void run() { try { TestTableProvider setting = new TestTableProvider(shell); setting.open(); } catch (Exception e) { e.printStackTrace(); } } }); } public static void main(String[] args) { showTable(null); }}
实现ITableLabelProvider接口
如果数据对象中没有定义getter方法,ViewSupport.bind方法就没办法用了。
通过看前面ViewSupport.bind方法的实现代码可以知道,ViewSupport.bind方法中为TableViewer提供了一个ObservableMapLabelProvider对象,实现对数据对象的解析。ObservableMapLabelProvider对象实现了ITableLabelProvider接口,这个接口为Tabler提供每个单元显示的text/image对象。
ITableLabelProvider原文说明:
Extends IBaseLabelProvider with the methods to provide the text and/or image for each column of a given element. Used by table viewers.
So,只要实现ITableLabelProvider接口就能为任意类型的数据对象提供每个单元的显示文本。
下图为ITableLabelProvider所在的层次结构图,
虽然ITableLabelProvider只有两个方法,但其父类接口IBaseLabelProvider却还有4个方法。所以如果要直接实现ITableLabelProvider接口,就要实现6个方法,即麻烦也没必要,因为IBaseLabelProvider之下的BaseLabelProvider类,提供了IBaseLabelProvider接口的基本实现,所以,只要自定义的TableLabelProvider,只需要继承BaseLabelProvider再实现ITableLabelProvider就可以了。
So,下面就是根据需求实现的自定义PairTableLabelProvider
class PairTableLabelProviderextends BaseLabelProvider implements ITableLabelProvider{ @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { Pair pair=(Pair) element; switch(columnIndex){ case 0:return pair.a.toString(); case 1:return pair.b.toString(); default:return null; } } }
有了PairTableLabelProviderextends类,就可以参照ViewSupport.bind方法实现数据TableViewer与数据对象的绑定了,核心代码如下:
TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION); table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn tblclmnId = new TableColumn(table, SWT.NONE); tblclmnId.setWidth(100); tblclmnId.setText("ID"); TableColumn tblclmnName = new TableColumn(table, SWT.NONE); tblclmnName.setWidth(100); tblclmnName.setText("Name"); // 以上代码与之前相同 tableViewer.setContentProvider(new ObservableListContentProvider()); // 将PairTableLabelProvider作为LabelProvider提供给tableViewer tableViewer.setLabelProvider(new PairTableLabelProvider()); // 这里使用org.eclipse.core.internal.databinding.Pair作为数据对象元素的类 // org.eclipse.core.internal.databinding.Pair没有getter方法获取类成员变量 IObservableList<Pair> input=createInput();// 创建ObservableList作为输入 tableViewer.setInput(input);
完整的测试代码
以下是WindowBuilder生成的测试代码。
TestTableProvider3.java
package testwb;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import org.eclipse.core.databinding.observable.Realm;import org.eclipse.core.databinding.observable.list.IObservableList;import org.eclipse.core.databinding.property.Properties;import org.eclipse.core.internal.databinding.Pair;import org.eclipse.jface.databinding.swt.DisplayRealm;import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;import org.eclipse.jface.dialogs.Dialog;import org.eclipse.jface.dialogs.IDialogConstants;import org.eclipse.swt.graphics.Image;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Control;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.layout.FillLayout;import org.eclipse.swt.SWT;import org.eclipse.swt.widgets.Table;import org.eclipse.swt.widgets.TableColumn;import org.eclipse.jface.viewers.BaseLabelProvider;import org.eclipse.jface.viewers.ITableLabelProvider;import org.eclipse.jface.viewers.TableViewer;public class TestTableProvider3 extends Dialog { class PairTableLabelProvider extends BaseLabelProvider implements ITableLabelProvider{ @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { Pair pair=(Pair) element; switch(columnIndex){ case 0:return (String) pair.a; case 1:return (String) pair.b; default:return null; } } } private Table table; /** * Create the dialog. * @param parentShell */ public TestTableProvider3(Shell parentShell) { super(parentShell); } /** * Create contents of the dialog. * @param parent */ @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(new FillLayout(SWT.HORIZONTAL)); TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION); table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn tblclmnId = new TableColumn(table, SWT.NONE); tblclmnId.setWidth(100); tblclmnId.setText("ID"); TableColumn tblclmnName = new TableColumn(table, SWT.NONE); tblclmnName.setWidth(100); tblclmnName.setText("Name"); tableViewer.setContentProvider(new ObservableListContentProvider()); tableViewer.setLabelProvider(new PairTableLabelProvider()); tableViewer.setInput(createInput()); return container; } /** * Create contents of the button bar. * @param parent */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } @Override protected void configureShell(Shell newShell) { newShell.setText("数据标签"); super.configureShell(newShell); } private IObservableList<Pair> createInput(){ List<String> names=Arrays.asList("face","car","bus"); ArrayList<Pair> list = new ArrayList<Pair>(); for(int i=0;i<names.size();++i){ list.add(new Pair(i,names.get(i))); } return Properties.<Pair>selfList(Pair.class).observe(list); } public static void showAnnotationTable(Shell shell, List<String> selectedFilters){ Display display = null==shell?Display.getDefault():shell.getDisplay(); Realm.runWithDefault(DisplayRealm.getRealm(display), new Runnable() { public void run() { try { TestTableProvider3 setting = new TestTableProvider3(shell); setting.open(); } catch (Exception e) { e.printStackTrace(); } } }); } public static void main(String[] args) { showAnnotationTable(null, null); }}
参考资料
《viewersupport》
- jface databinding:label provider 实现多列表格(Table)数据绑定的两个途径
- jface databinding:重写doSetValue方法ComputedValue实现双向多对一的数据绑定
- jface databinding:更简单的ISideEffect实现多目标单边数据绑定塈其原理分析
- jface databinding:使用CheckboxTableViewer实现表中(Set)对象与CheckTable中选中条目数据绑定
- jface databinding: Radio Button group及ISideEffect绑定数据对象的例子
- 分两个table呈现数据列(奇偶记录序数列绑定到不同的table的解决方案)
- bootstrap-table实现两个表格之间数据的传递,表格添加行删除行功能
- jface databinding:可多选的widget List组件selection项目与java.util.List对象的双向数据绑定
- easyUI的table表格怎么实现将每一行中某几列数据相加放入另一列
- jface databinding/PojoBindable实现对POJO对象的支持
- jface databinding:部分实现POJO对象的监测
- SWT/JFace中Table相同列多种类型CellEditor以及参照类型编辑器的实现
- 获取table表格每行每列的数据
- JFace 数据绑定
- 数据绑定技术-databinding
- 数据绑定框架:Databinding
- asp.net中用table表格绑定数据
- easyUI的table表格怎么实现将某一列数据之和放入新追加的一行中
- 浅谈Java中path、classpath环境变量的配置问题
- How to Install PHP 7 on CentOS/RHEL 7.1 & 6.7
- 特殊字符<200b><200c><200d>的删除办法与原理
- yum 安装mysql5.7 是 出现无法登陆问题以及mysql error You must reset your password using ALTER USER statement befor
- java POI word的docx文档中的文字替换,并把docx转成pdf文档
- jface databinding:label provider 实现多列表格(Table)数据绑定的两个途径
- rails g -h
- Linux的用户组和权限管理之特殊权限及ACL的使用
- 事件分发机制
- Android图片加载Glide框架使用详解
- VS+QT环境搭建
- TypeScript学习笔记之基本类型
- Swift: How to convert a String to UInt8 array?
- Spring MVC JSR 303 数据效验