2

我有一个设置,我不想使用一个 FormFieldFactory,它返回一个表单,该表单也有一个带有 FormFieldFactory 的表单。

我的实体是具有名称和价格集合的订阅。价格具有国家和价格。我有一个表单来呈现订阅,并且附加的 FormFieldFactory 返回一个 TextField 作为名称,另一个表单返回价格实体。价格实体表单返回一个表,其中每个价格都应显示为一个项目。

我的问题是我无法让它工作。结果只是一个包含订阅的页面,没有其他内容。两个 FormFieldFactories 都被调用并在最后返回一个 Table ,因此进行了预期的调用。

令我困惑的一件事是 PriceFormFieldFactory.createField() 被调用了两次,第一次使用包含我的集合的属性“prices”,第二次使用包含值“false”的属性“empty”。我希望这只是一个电话,因为我只有一个订阅和一个收藏。

有人可以启发我吗?

托马斯

编码:

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.*;

import java.util.ArrayList;
import java.util.Collection;

public class SubscriptionComponent extends CustomComponent {
    private HorizontalLayout mainLayout;

    public SubscriptionComponent() {
        buildMainLayout();
    }

    private void buildMainLayout() {
        mainLayout = new HorizontalLayout();
        mainLayout.setSizeFull();
        mainLayout.setSpacing(true);

        Subscription subscription = createSubscription();

        mainLayout.addComponent(new SubscriptionForm(subscription));
        setCompositionRoot(mainLayout);
    }

    private Subscription createSubscription() {
        Collection<Price> prices = new ArrayList<Price>();
        prices.add(new Price("Elbonia", 1));
        prices.add(new Price("El Honduragua", 2));
        return new Subscription("First subscription", prices);
    }

    public class Subscription {
        private String name;
        private Collection<Price> prices;

        public Subscription(String name, Collection<Price> prices) {
            this.name = name;
            this.prices = prices;
        }

        public String getName() {
            return name;
        }

        public Collection<Price> getPrices() {
            return prices;
        }
    }

    public class SubscriptionForm extends Form {

        public SubscriptionForm(Subscription subscription) {
            setFormFieldFactory(new SubscriptionFormFieldFactory());
            setItemDataSource(new BeanItem<Subscription>(subscription));
        }
    }

    public class SubscriptionFormFieldFactory implements FormFieldFactory {
        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            String pid = (String) propertyId;
            if (pid.equals("name")) {
                return new TextField();
            } else if (pid.equals("prices")) {
                Collection<Price> prices = (Collection<Price>) item.getItemProperty("prices").getValue();
                return new PriceForm(prices);
            }

            return null;
        }
    }

    public class PriceForm extends Form {
        public PriceForm(Collection<Price> prices) {
            setFormFieldFactory(new PriceFormFieldFactory());
            setItemDataSource(new BeanItem<PriceFormItem>(new PriceFormItem(prices)));
        }
    }

    public class PriceFormFieldFactory implements FormFieldFactory {
        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            String pid = (String) propertyId;
            if (pid.equals("prices")) {
                return new PriceTable(new PriceContainer((Collection<Price>) item.getItemProperty("prices").getValue()));
            }
            return null;
        }
    }

    public class PriceFormItem {
        private Collection<Price> prices;

        public PriceFormItem(Collection<Price> prices) {
            this.prices = prices;
        }

        public Collection<Price> getPrices() {
            return prices;
        }
    }

    public enum PriceColumns {
        name("Name"), price("Price");

        private String value;

        PriceColumns(String value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return value;
        }
    }

    public class PriceContainer extends BeanItemContainer<Price> {
        public PriceContainer(Collection<Price> prices) {
            super(Price.class);
            for (Price price : prices) {
                addItem(price);
            }
        }
    }

    public class Price {
        private String country;
        private double price;

        public Price(String name, double price) {
            this.country = name;
            this.price = price;
        }

        public String getCountry() {
            return country;
        }

        public double getPrice() {
            return price;
        }
    }

    public class PriceTable extends Table {
        public PriceTable(PriceContainer countryRatesContainer) {
            setContainerDataSource(countryRatesContainer);

            setColumnCollapsingAllowed(true);
            setColumnReorderingAllowed(true);

            setColumnExpandRatio(PriceColumns.name.name(), .7f);
            setColumnAlignment(PriceColumns.price.name(), ALIGN_CENTER);
        }
    }
}

这已交叉发布在:http: //vaadin.com/forum/-/message_boards/message/302906

4

1 回答 1

1

我找到了我的问题的答案——不是我喜欢它,但至少我现在可以专注于寻找另一个解决方案。似乎其他人已经尝试做我想要完成的事情,并发现目前 Vaadin 没有这样做:

嵌套表单:嵌套表单不可见

所以现在我将改变布局计划并找到另一种方法来做我想做的事。

托马斯

于 2011-02-22T22:03:09.030 回答