在Tapestry中通用的property selection model
Tapestry中构建选择列表需要使用IPropertySelectionModel,Model可以映射选择列表中的Label和Option,Tapestry中已经提供一个常用的StringSelectonModel,具体组件使用如下:<o:p></o:p>
Html代码<o:p></o:p>
Java代码
- public abstract class DetailsPage extends BasePage {
- public static final IPropertySelectionModel GENDER_MODEL =
- new StringPropertySelectionModel(new String[] { "Unspecified", "Female", "Male" });
- public abstract String getGender();
- public void formSubmit(IRequestCycle cycle) {
- // Process form submission
- String genderSelection = getGender();
- ...
- }
- }
开发中比较常见的选择列表就是类别的选择,,一般是新建一个类别的SelectionModel,例如如下代码
- public class TypeSelectionModel implements IPropertySelectionModel, Serializable {
- private List TypeList;
- public ItemSelectionModel(List typeList) {
- this. typeList = typeList;
- }
- public int getOptionCount() { return typeList.size(); }
- public Object getOption(int index) {
- return ((Type)typeList.get(index)).getId();
- }
- public String getLabel(int index) {
- return ((Type) typeList.get(index)).getName();
- }
- public String getValue(int index) { return Integer.toString(index); }
- public Object translateValue(String value) {
- return getOption(Integer.parseInt(value));
- }
- }
这只是传统方法,开发中的类别如果多了,每一个都要新建一个SelectionModel。
下面是在Tapestry JumpStart里看到的通用的SelectionModel,感觉比较不错,现介绍给大家,具体代码如下:
- package com.javaeye.tapestrying.selectionModel;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.tapestry.form.IPropertySelectionModel;
-
- public class ObjectPropertySelectionModel implements IPropertySelectionModel {
- private List _list;
- private Method _methodToGetLabel = null;
- private Method _methodToGetOption = null;
- private boolean _allowNoSelection = false;
- private String _noSelectionMessage = null;
- private int _offset = 0;
- public ObjectPropertySelectionModel() {
- _list = new ArrayList();
- throw new UnsupportedOperationException("Do not use the default constructor.");
- }
- /**
- *
- * @param list
- * the list of objects to represent in a PropertySelection
- * component. WARNING: The objects in the list MUST implement
- * equals(Object obj) and hashCode(), and if they are EJB3
- * Entities those methods MUST return the same thing for
- * different instances of the same detached entity (eg. by
- * matching on Id only).
- * @param clazz
- * the class of objects in the list.
- * @param nameOfMethodToGetLabel
- * the name of the method that PropertySelection must invoke on
- * each object in the list to get its label to display in the
- * list on the page. For example, the method name might be
- * "getShortName".
- * @param nameOfMethodToGetOption
- * the name of the method that PropertySelection must invoke on
- * an object when it has been selected. The result is put into
- * the property named in the "value" parameter of the
- * PropertySelection. For example, the method name might be
- * "getKey". If you want the result to be the the whole object
- * then set this argument to null.
- *
- */
- public ObjectPropertySelectionModel(Listextends Object> list, Class clazz, String nameOfMethodToGetLabel,
- String nameOfMethodToGetOption) { this(list, clazz, nameOfMethodToGetLabel, nameOfMethodToGetOption, false, null);
- }
- /**
- *
- * @param list
- * the list of objects to represent in a PropertySelection
- * component. WARNING: The objects in the list MUST implement
- * equals(Object obj) and hashCode(), and if they are EJB3
- * Entities those methods MUST return the same thing for
- * different instances of the same detached entity (eg. by
- * matching on Id only).
- * @param clazz
- * the class of objects in the list.
- * @param nameOfMethodToGetLabel
- * the name of the method that PropertySelection must invoke on
- * each object in the list to get its label to display in the
- * list on the page. For example, the method name might be
- * "getShortName".
- * @param nameOfMethodToGetOption
- * the name of the method that PropertySelection must invoke on
- * an object when it has been selected. The result is put into
- * the property named in the "value" parameter of the
- * PropertySelection. For example, the method name might be
- * "getKey". If you want the result to be the the whole object
- * then set this argument to null.
- * @param allowNoSelection
- * If true then adds an element to the start of the list. Its
- * option is null.
- * @param noSelectionLabel
- * If null then no label. A typical label might be "Select...".
- *
- */
- public ObjectPropertySelectionModel(Listextends Object> list, Class clazz, String nameOfMethodToGetLabel,
- String nameOfMethodToGetOption, boolean allowNoSelection, String noSelectionLabel) {
- try {
- _list = list;
- _methodToGetLabel = clazz.getMethod(nameOfMethodToGetLabel, (Class[]) null);
- if (nameOfMethodToGetOption != null) {
- _methodToGetOption = clazz.getMethod(nameOfMethodToGetOption, (Class[]) null);
- }
- _allowNoSelection = allowNoSelection;
- if (_allowNoSelection) {
- _noSelectionMessage = noSelectionLabel;
- _offset = 1;
- }
- }
- catch (SecurityException e) {
- throw new IllegalStateException(e);
- }
- catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("Given nameOfMethodToGetLabel=\"" + nameOfMethodToGetLabel + "\", nameOfMethodToGetOption=\""
- + nameOfMethodToGetOption + "\", class=\"" + clazz + "\".", e);
- }
- }
- public int getOptionCount() {
- return _list.size() + _offset;
- }
- public Object getOption(int index) {
- if (_allowNoSelection) {
- if (index < _offset) {
- return null;
- }
- }
- Object o = _list.get(index - _offset);
- if (_methodToGetOption == null) {
- return o;
- }
- else {
- try {
- Object option = _methodToGetOption.invoke(o, (Object[]) null);
- return option;
- }
- catch (IllegalArgumentException e) {
- throw new IllegalStateException("Problem with the given methodToGetOption \"" + _methodToGetOption + "\": ", e);
- }
- catch (IllegalAccessException e) {
- throw new IllegalStateException("Problem with the given methodToGetOption \"" + _methodToGetOption + "\": ", e);
- }
- catch (InvocationTargetException e) {
- throw new IllegalStateException("Problem with the given methodToGetOption \"" + _methodToGetOption + "\": ", e);
- }
- }
- }
- public String getLabel(int index) {
- if (_allowNoSelection) {
- if (index < _offset) {
- return _noSelectionMessage;
- }
- }
- Object o = _list.get(index - _offset);
- try {
- String label = _methodToGetLabel.invoke(o, (Object[]) null).toString();
- return label;
- }
- catch (IllegalArgumentException e) {
- throw new IllegalStateException("Problem with the given methodToGetLabel \"" + _methodToGetOption + "\": ", e);
- }
- catch (IllegalAccessException e) {
- throw new IllegalStateException("Problem with the given methodToGetLabel \"" + _methodToGetOption + "\": ", e);
- }
- catch (InvocationTargetException e) {
- throw new IllegalStateException ("Problem with the given methodToGetLabel \"" + _methodToGetOption + "\": ", e);
- }
- }
- public String getValue(int index) {
- return Integer.toString(index);
- }
- public Object translateValue(String value) {
- return value == null ? null : getOption(Integer.parseInt(value));
- }
- }
具体使用如下,假如现在有一个配件类型的类
- public class FittingType {
- private Long id;
- private String name;
- private Set<fitting></fitting> fittings = new HashSet<fitting></fitting>();
- //getter and setter
- }
<o:p></o:p>
创建配件类时,需要选择配件类型
- private IPropertySelectionModel fittingTypeSelectionModel;
- public IPropertySelectionModel getFittingTypeSelectionModel() {
- if (fittingTypeSelectionModel == null) {
- List<fittingtype></fittingtype> fittingTypes = getFittingTypeService().findAll();
- fittingTypeSelectionModel = new ObjectPropertySelectionModel(
- fittingTypes, FittingType.class, "getName", "getId", true,
- "选择分类");
- }
- return fittingTypeSelectionModel;
- }
- public abstract Long getFittingTypeId();
- public ILink onSave() {
- //其他
- if (getFittingTypeId() != null) {
- fitting.setType(getFittingTypeService()
- .findByID(getFittingTypeId()));
- }
- //其他
- }
Html中定义组件<o:p></o:p>
- "type@PropertySelection" model="ognl:fittingTypeSelectionModel" value="ognl:fittingTypeId" displayName="配件类型"/>
<o:p> </o:p>
具体定义中
fittingTypeSelectionModel = new ObjectPropertySelectionModel(<o:p></o:p>
fittingTypes, FittingType.class, "getName", "getId", true,<o:p></o:p>
"选择分类");<o:p></o:p>
}<o:p></o:p>
参数1:候选的List
参数2:类别
参数3:label的getter方法
参数4:option的getter方法
参数5:是否允许没有选项
参数6:没有选项时的label
<o:p> </o:p>
好了,项目中又多了个通用的东西,开发时又可以happy了。
- "@PropertySelection" model="ognl:@com.myexample.DetailsPage@GENDER_MODEL" value="ognl:gender"/>
下一篇: Java基础——面向对象和构造器