BindMapping介绍
BindMapping 是代表一系列的 BindMapping接口,这组接口用于pivot的 DataBind过程。
BindMapping包含一系列以BindMapping结尾命名的接口。下面列出了大部分pivot所支持的BindMapping接口
TextBindMapping--用于 Label、TextInput和TextArea等控件内容为String的控件。
StateBindMapping--用于 Toggle 按钮(Checkbox和Radio)按钮的三态的绑定。例如某个类型为boolean并且允许空值的数据库字段。
SelectedBindMapping--用于Togglea按钮的选中与非选中状态
ListDataBindMapping--由于 Pivot框架重新实现了一套集合框架。如果业务逻辑使用的List是java.util.List对象时,需要转换为Pivot框架对应的集合对象。
ItemBindMapping--用于ListView等列表组件的选中项的绑定。
SpinnerDataBindMapping 与 ListDataBindMapping 类似
TableDataBindMapping TableView数据内容的绑定,与ListDataBindMapping类似
SelectedRowBindMapping
SelectedDateBindMapping
SelectedColorBindMapping
何时使用BindMapping:符合下面的情况时,不需要使用BindMapping
1. 控件的显示内容(Label,TextInput显示文本,ToggleButton显示 true或者false状态..)与Bean 属性的数据类型相同时
2. Bean属性的数据类型有内置方法可以转换为控件的显示内容的数据类型
例如 Lable,TextInput的内容为String,因此只要Bean属性的对象支持 toString方法即可。
符合以上2点时,用户可以选择不使用BindMapping,pivot框架在调用load和stroe时会使用每个控件的内置BindMapping(无)。
大多数情况下使用BindMapping时,是在数据类型不匹配时,比如TextInput显示一个Integer类型的Bean属性时。此时如果只是load模式,可以不提供。如果是STROE或者BOTH模式需要提供BindMapping。
TextBindMappingInt类 实现了了Integer数据类型到String之间的数据绑定的转换,该类的实例可以用于 Label、TextInput、TextArea等控件内容为String绑定到整数字段的组件。
下面代码演示几个常用的 BindMapping
import org.apache.pivot.wtk.TextInput.TextBindMapping; /** * 用于实现 string <==> integer 之间的转换 */ public class TextBindMappingInt implements TextBindMapping { @Override public String toString(Object value) { // TODO Auto-generated method stub return value.toString(); } @Override public Object valueOf(String text) { // TODO Auto-generated method stub if ( text == null || text.equals("")) { return 0; } return Integer.parseInt(text); } } /* TextBindMappingIP 类: 用于Bean属性为整数的IPv4地址时,转换为点分格式的String文本时使用。 */ import java.net.InetSocketAddress; import org.apache.pivot.wtk.TextInput.TextBindMapping; public class TextBindMappingIP implements TextBindMapping { @Override public String toString(Object value) { // TODO Auto-generated method stub if ( value instanceof Integer) { int ip = ((Integer)value).intValue(); int [] addr = new int[4]; addr[3] = (( (ip & 0xFF000000) >>> 24) & 0xFF); addr[2] = (( (ip & 0x00FF0000) >>> 16) & 0xFF); addr[1] = (( (ip & 0x0000FF00) >>> 8) & 0xFF); addr[0] = ( (ip & 0x000000FF) & 0xFF); return (addr[0]+"."+addr[1]+"."+addr[2]+"."+addr[3]); } return null; } @Override public Object valueOf(String text) { if ( text == null || text.equals("")) return 0; InetSocketAddress addr = new InetSocketAddress(text, 0); byte[] ip = addr.getAddress().getAddress(); if (ip == null) { return 0; } int value = 0; value = ( ((int)ip[3]) << 24) & 0xff000000 | ( (int)ip[2] << 16) & 0x00ff0000 | ( (int)ip[1] << 8) & 0x0000ff00 | ((int)ip[0]) & 0x000000ff; return value; } } /* ItemBindMappingEnum 用于实现 枚举值和控件内容之间的转换,一般用于ListButton的选中项。 */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.pivot.collections.List; import org.apache.pivot.wtk.ListView.ItemBindMapping; import com.google.protobuf.ProtocolMessageEnum; public class ItemBindMappingEnum implements ItemBindMapping { private String enumName; @Override public Object get(List<?> listData, int index) { // TODO Auto-generated method stub try { //System.out.println(enumName+":"+index); Class<?> classObj = Class.forName(enumName); Method valueOf = classObj.getMethod("values", new Class<?>[]{}); Object [] ar = ((Object[])valueOf.invoke(null, new Object[] { })); //for( Object e : ar) //{ // System.out.println(e.toString()); //} if ( index >= ar.length ) { //System.out.println("index error:"+index); return ar[0]; } return ar[index]; } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override public int indexOf(List<?> listData, Object value) { // TODO Auto-generated method stub if ( value instanceof ProtocolMessageEnum ) { Enum<?> msgEnum = (Enum<?>)value; return msgEnum.ordinal(); }else if ( value instanceof Enum<?>) { Enum<?> enumValue = (Enum<?>)value; return enumValue.ordinal(); } return 0; } public void setEnumName(String enumName) { this.enumName = enumName; } public String getEnumName() { return enumName; } } /* ListDataBindMappingList 用于 ListView 等控件内容为一个列表时。由于Pivot的控件支持的集合框架为org.apache.pivot.collections中的数据类型,而应用程序一般提供的数据类型都是为 java.util.List的对象,此时ListView等控件无法直接显示内容,因此需要在源数据内容和目标数据内容之间设置一个BindMapping,进行数据类型的转换。默认情况下ListView只能的Item只能显示List的元素类型为ListItem的对象,如果非ListItem的对象必须提供toString方法或者未ListView提供一个适合元素对象的ItemRenderer实例。或许你需要了解更多有关Pivot Renderer的内容。 */ import org.apache.pivot.collections.ArrayList; import org.apache.pivot.collections.List; import org.apache.pivot.wtk.ListView.ListDataBindMapping; import org.apache.pivot.wtk.content.ListItem; import com.google.protobuf.ByteString; import dv.Dvmessage.IPAddress; /*List元素的内容的某种数据类型*/ public class ListDataBindMappingList implements ListDataBindMapping { private boolean toInteger = false; // 是否把 ListItem 转换为 Integer private boolean toByteString = false; private boolean toIP = false; @Override public List<?> toListData(Object value) { // TODO Auto-generated method stub List<Object> listData = new ArrayList<Object>(); if ( value instanceof java.util.List<?>) { java.util.List<?> jList = (java.util.List<?>)value; if ( jList.size() == 0 ) { return listData; } for( Object e : jList) { if ( toInteger ) { ListItem item = new ListItem(e.toString()); listData.add(item); }else if ( toByteString ) { ByteString bs = (ByteString)e; String strBs = new String( bs.toByteArray()); ListItem item = new ListItem(strBs); listData.add(item); }else if ( toIP) { TextBindMappingIPAndPort textToIP = new TextBindMappingIPAndPort(); if ( e instanceof IPAddress ) { listData.add( new ListItem(textToIP.toString(e))); } } else { listData.add(e); /*不做任何类型转换,用户需要提供代对象的 ItemRenderer或者提供 toString方法,元素内容才可以正常显示*/ } } } return listData; } @Override public Object valueOf(List<?> listData) { // TODO Auto-generated method stub java.util.List<Object> jList = new java.util.ArrayList<Object>(); if ( listData instanceof List<?>) { List<?> list = ( List<?>)listData; for( Object e: list ) { if ( toInteger ) { if ( e instanceof ListItem ) { ListItem item = (ListItem)e; jList.add( Integer.parseInt( item.getText())); } }else if ( toByteString ) { if ( e instanceof ListItem) { ListItem item = (ListItem)e; jList.add( ByteString.copyFrom( item.getText().getBytes())); } }else if ( toIP) { TextBindMappingIPAndPort textToIP = new TextBindMappingIPAndPort(); if ( e instanceof ListItem ) { ListItem item = (ListItem)e; jList.add( textToIP.valueOf(item.getText())); } } else { jList.add(e); } } } if ( jList.size() == 0 ) { return java.util.Collections.emptyList(); } return jList; } public void setToInteger(boolean toInteger) { this.toInteger = toInteger; } public boolean isToInteger() { return toInteger; } public boolean isToIP() { return toIP; } public void setToIP(boolean toIP) { this.toIP = toIP; } public void setToByteString(boolean toByteString) { this.toByteString = toByteString; } public boolean isToByteString() { return toByteString; } }
使用BindMapping,在wtkx文件中引用
<?xml version="1.0" ?> <Border xmlns="org.apache.pivot.wtk" xmlns:collections="org.apache.pivot.collections" xmlns:content="org.apache.pivot.wtk.content" xmlns:wtkx="http://pivot.apache.org/wtkx" xmlns:bind="cn.dvision.bindMapping" xmlns:renderer="cn.dvision.ui.renderer" xmlns:custom="cn.dvision.ui"> <content> <ScrollPane> <view> <Form> <sections> <Form.Section> <custom:ListButtonEnumData enumName="dv.Dvenum$IPType" selectedItemKey="type" Form.label="type"> <selectedItemBindMapping> <bind:ItemBindMappingEnum enumName="dv.Dvenum$IPType"/> </selectedItemBindMapping> </custom:ListButtonEnumData> <BoxPane Form.label="ipv4"> <TextInput textKey="ipv4"> <textBindMapping> <bind:TextBindMappingIP/> </textBindMapping> </TextInput> <Checkbox selectedKey="hasIpv4"/> </BoxPane> <BoxPane Form.label="ipv6"> <TextInput textKey="ipv6"> <textBindMapping> <bind:TextBindMappingByteString/> </textBindMapping> </TextInput> <Checkbox selectedKey="hasIpv6"/> </BoxPane> <BoxPane Form.label="domain"> <TextInput textKey="domain"/> <Checkbox selectedKey="hasDomain"/> </BoxPane> <TextInput textKey="port" Form.label="port"> <textBindMapping> <bind:TextBindMappingInt/> </textBindMapping> </TextInput> </Form.Section> </sections> </Form> </view> </ScrollPane> </content> </Border>
即可: