java 代码
- Eureka!
- Finally got it all working. What caused the drop down to not be
- defaulting is the fact that I declared my "Brand" list in two separate
- lists... One for the ValueEncoder and one for the SelectModel. Big no
- no! An "equals" is called on the value from the SelectModel and the
- value from the ValueEncoder, so if they are initialized as separate
- objects in separate lists the framework won't notice that they are equal
- (because they would point to a different memory location). I found that
- the framework also seems to like things better if the List of Brands is
- "@Persist"ed between pages. Here's the final source code that I used to
- get it all working (Enjoy!):
- Brand.java (simple POJO):
- public class Brand {
- private String id;
- private String description;
- public Brand() {}
- public Brand(String id, String description) {
- this.id = id;
- this.description = description;
- }
- public String getId() {
- return id;
- }
- public String getDescription() {
- return description;
- }
- }
- Test.java
- public class Test {
- @Persist
- private Brand brand;
- @Persist
- private List<Brand> brands;
- public Brand getBrand() {
- return brand;
- }
- public void setBrand(Brand brand) {
- this.brand = brand;
- }
- private List<Brand> getBrands()
- {
- if(brands == null) {
- brands = new ArrayList<Brand>();
- brands.add(new Brand("1", "Brand 1"));
- brands.add(new Brand("2", "Brand 2"));
- brands.add(new Brand("3", "Brand 3"));
- brands.add(new Brand("4", "Brand 4"));
- }
- return brands;
- }
- public BrandSelectModel getBrandSelectModel() {
- return new BrandSelectModel(getBrands());
- }
- public BrandValueEncoder getBrandValueEncoder() {
- return new BrandValueEncoder(getBrands());
- }
- public class BrandValueEncoder implements ValueEncoder<Brand> {
- private List<Brand> brands;
- public BrandValueEncoder(List<Brand> brands) {
- this.brands = brands;
- }
- public String toClient(Brand brand) {
- return brand.getDescription();
- }
- public Brand toValue(String string) {
- for(Brand brand : brands) {
- if(brand.getDescription().equals(string)) {
- return brand;
- }
- }
- return null;
- }
- }
- public class BrandSelectModel implements SelectModel {
- private List<Brand> brands;
- public BrandSelectModel(List<Brand> brands) {
- this.brands = brands;
- }
- public List<OptionGroupModel> getOptionGroups() {
- return null;
- }
- public List<OptionModel> getOptions() {
- List<OptionModel> optionModelList = new
- ArrayList<OptionModel>();
- for(Brand brand: brands) {
- optionModelList.add(
- new OptionModelImpl(
- brand.getDescription(),
- false,
- brand,
- new String[0]
- )
- );
- }
- return optionModelList;
- }
- }
- }
xml 代码
- Test.html
- <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
- <t:form>
- <select t:type="select" t:id="brand"
- value="brand" model="brandSelectModel"
- encoder="brandValueEncoder"
- onchange="this.form.submit();" />
- <br/>
- <t:if test="brand">
- ${brand.description}
- </t:if>
- </t:form>
- </html>
Eureka! 最终调试好的代码:BrandSelectModel 和BrandValueEncoder 写的都挺完美的,要比我写的流畅多了,把List brands 作为参数传入,很符合写Swing程序时候的习惯,如果作为全局变量就显的混乱的多。另外 toClient(Brand brand) 接口里的声明是Object 类型,在我这里会报错。真希望多一些这样的classic demo。
<brand> <brand> <brand> <brand> <brand> <brand> <brand> <brand> <optiongroupmodel> <optionmodel> <optionmodel> <optionmodel></optionmodel> </optionmodel> </optionmodel> </optiongroupmodel> </brand></brand></brand></brand></brand></brand></brand></brand></brand>