Dear Wiki user, You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for change notification.
The following page has been changed by MarceloLotif: http://wiki.apache.org/tapestry/Tapestry5AnotherSelectWithObjects The comment on the change is: Bugs fixed ------------------------------------------------------------------------------ * [http://www.phy6.net/wiki/tiki-index.php?page=Tapestry+5+GenericSelectionModel Tapestry5 How to use the SELECT component] * ["Tapestry5DisplayableSelectionModel"] - Here, we will create an Annotation, a (not so) new feature from Java 1.5, widely know by Tapestry users, to suppress some steps from the other methods, like the instantiation of a SelectionModel and a ValueEncoder, or even create another component to do the job. Remember, this is an extension, so everything we saw in the other components are presented here. What I tried to do is an easier way of instantiate the component in the page class. + Here, we will create an Annotation, a (not so) new feature from Java 1.5, widely known by Tapestry users, to suppress some steps from the other methods, like the instantiation of a SelectionModel and a ValueEncoder, or even create another component to do the job. Remember, this is an extension, so everything we saw in the other components are presented here. What I tried to do is an easier way to instantiate the component in the page class. We will see 4 basic classes here: * '''GenericSelectionModel''' - This is the model that the component will use to render the options for your Select component. @@ -30, +30 @@ import org.apache.tapestry.util.AbstractSelectModel; public class GenericSelectionModel<T> extends AbstractSelectModel { - + private PropertyAdapter labelFieldAdapter = null; + private List<T> list; public GenericSelectionModel(List<T> list, String labelField, PropertyAccess access) { if(labelField != null && !labelField.equalsIgnoreCase("null")){ + if(list.size() > 0){ - this.labelFieldAdapter = access.getAdapter(list.get(0).getClass()).getPropertyAdapter(labelField); + this.labelFieldAdapter = access.getAdapter(list.get(0).getClass()).getPropertyAdapter(labelField); + } } this.list = list; } @@ -49, +52 @@ List<OptionModel> optionModelList = new ArrayList<OptionModel>(); for (T obj : list) { if (labelFieldAdapter == null) { - optionModelList.add(new OptionModelImpl(nvl(obj) + "", false, obj, new String[0])); + optionModelList.add(new OptionModelImpl(nvl(obj) + "", false, + obj, new String[0])); } else { - optionModelList.add(new OptionModelImpl(nvl(labelFieldAdapter.get(obj)), false, obj, new String[0])); + optionModelList.add(new OptionModelImpl(nvl(labelFieldAdapter + .get(obj)), false, obj, new String[0])); } } return optionModelList; } - + private String nvl(Object o) { - if (o == null) - return ""; - else - return o.toString(); - } - + if (o == null) + return ""; + else + return o.toString(); + } + } }}} @@ -83, +88 @@ public GenericValueEncoder(List<T> list, String idField, PropertyAccess access) { if (idField != null && !idField.equalsIgnoreCase("null")){ + if(list.size() > 0){ - this.idFieldAdapter = access.getAdapter(list.get(0).getClass()).getPropertyAdapter(idField); + this.idFieldAdapter = access.getAdapter(list.get(0).getClass()).getPropertyAdapter(idField); + } } this.list = list; } @@ -148, +155 @@ So, this way, you don't need to add these lines on every page you create, with every Select you make. You just have to decorate the Select's list with this annotation and it will insert them for you. - Pot this class on your ''sevices'' package: + Put this class on your ''sevices'' package: {{{ import java.lang.reflect.Modifier; - import org.apache.tapestry.ioc.internal.services.PropertyAccessImpl; import org.apache.tapestry.ioc.internal.util.InternalUtils; + import org.apache.tapestry.ioc.services.PropertyAccess; import org.apache.tapestry.ioc.util.BodyBuilder; import org.apache.tapestry.model.MutableComponentModel; import org.apache.tapestry.services.ClassTransformation; @@ -169, +176 @@ public class InjectSelectionModelWorker implements ComponentClassTransformWorker { final private Logger _logger = LoggerFactory.getLogger(InjectSelectionModelWorker.class); + final private PropertyAccess _access; + public InjectSelectionModelWorker(PropertyAccess propertyAccess) { + _access = propertyAccess; + } + public void transform(ClassTransformation transformation, MutableComponentModel componentModel) { for (String fieldName : transformation.findFieldsWithAnnotation(InjectSelectionModel.class)) { @@ -180, +192 @@ } String accessActualName = transformation.addField(Modifier.PRIVATE, "org.apache.tapestry.ioc.services.PropertyAccess", "_access"); - transformation.injectField(accessActualName, new PropertyAccessImpl()); + transformation.injectField(accessActualName, _access); addGetSelectionModelMethod(transformation, fieldName, annotation.labelField(), accessActualName); @@ -197, +209 @@ private void addGetSelectionModelMethod(ClassTransformation transformation, String fieldName, String labelField, String accessName) { String methodName = "get" + InternalUtils.capitalize(InternalUtils.stripMemberPrefix(fieldName)) + "SelectionModel"; - + String modelQualifiedName = (GenericSelectionModel.class).getName(); TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, modelQualifiedName, methodName, null, null); @@ -241, +253 @@ * <li>InjectSelectionModel - generates the SelectionModel and ValueEncoder for a any marked list of objects.</li> * </ul> */ - public static void contributeComponentClassTransformWorker(OrderedConfiguration<ComponentClassTransformWorker> configuration) + public static void contributeComponentClassTransformWorker(OrderedConfiguration<ComponentClassTransformWorker> configuration, PropertyAccess propertyAccess) { - configuration.add("InjectSelectionModel", new InjectSelectionModelWorker(), "after:Inject*"); + configuration.add("InjectSelectionModel", new InjectSelectionModelWorker(propertyAccess), "after:Inject*"); } }}} So, let's use it: - First, declare a list and populate it. Put the annotation on the list and pass the '''labelField'' and '''idField'' attributes to it. Then, create the item to get the selection. + First, declare a list and populate it. Put the annotation on the list and pass the '''labelField''' and '''idField''' attributes to it. Then, create the item to get the selection. Here's the example: {{{ @@ -312, +324 @@ }}} - If you wnat to have a '''List<String>''', just instantiate it and pass '''nothing''' as the ''labelField'' and ''idField'' for the annotation. + If you want a '''List<String>''', just instantiate it and pass '''nothing''' as the ''labelField'' and ''idField'' for the annotation. '''Important:''' your bean have to override the '''equals()''' method from the '''Object''' superclass, so the component can compare your current selection with the appropriate bean inside the list. The Eclipse IDE provide a simple default implementation that solves the problem. Go to the menu '''"Source/Generate hashCode() and equals()..."''' to use this feature. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
