Как отобразить изображения в таблице Vaadin 6?

У меня есть приложение Vaadin 6, в котором я хочу отобразить несколько изображений в таблице.

Для этого я определяю следующую модель данных.

private BeanContainer<byte[],UserProductImageBean> productImageData;
productImageData = new BeanContainer<byte[],
        UserProductImageBean>(UserProductImageBean.class);
productImageData.setBeanIdProperty("userProductImageId");

Таблица определяется следующим образом.

productImagesTable = new Table("Product images", productImageData);
productImagesTable.setItemIconPropertyId("imageResource");

Я получаю данные изображения с сервера в виде UserProductImage экземпляры:

public class UserProductImage {
    private byte[] userProductImageId;
    private byte[] imageData;
    private byte[] userProductId;
    private String fileName;
    private String creatorEmail;
    private String mimeType;

    public byte[] getImageData() {
        return imageData;
    }

    public void setImageData(final byte[] aImageData) {
        imageData = aImageData;
    }

    public byte[] getUserProductId() {
        return userProductId;
    }

    public void setUserProductId(final byte[] aUserProductId) {
        userProductId = aUserProductId;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(final String aFileName) {
        fileName = aFileName;
    }

    public String getCreatorEmail() {
        return creatorEmail;
    }

    public void setCreatorEmail(final String aCreatorEmail) {
        creatorEmail = aCreatorEmail;
    }

    public String getMimeType() {
        return mimeType;
    }

    public void setMimeType(final String aMimeType) {
        mimeType = aMimeType;
    }

    public byte[] getUserProductImageId() {
        return userProductImageId;
    }

    public void setUserProductImageId(final byte[] aUserProductImageId) {
        userProductImageId = aUserProductImageId;
    }
}

Когда я обновляю данные таблицы, я конвертирую UserProductImage случаи в UserProductImageBean:

final List<UserProductImage> userProductImages = response.getUserImages();

for (final UserProductImage curImage : userProductImages)
{
    productImageData.addBean(UserProductImageBean.create(curImage,
            My.getInstance()));

}

UserProductImageBean добавляет свойство ресурса изображения:

public class UserProductImageBean extends UserProductImage {
    private UserProductImageResource imageResource;

    private UserProductImageBean()
    {
    }

    public UserProductImageResource getImageResource() {
        return imageResource;
    }

    public static UserProductImageBean create(final UserProductImage aUserProductImage,
                                              final Application aApplication)
    {
        final UserProductImageBean result = new UserProductImageBean();

        result.setImageData(aUserProductImage.getImageData());
        result.setUserProductId(aUserProductImage.getUserProductId());
        result.setCreatorEmail(aUserProductImage.getCreatorEmail());
        result.setMimeType(aUserProductImage.getMimeType());
        result.setFileName(aUserProductImage.getFileName());
        result.setUserProductImageId(aUserProductImage.getUserProductImageId());
        result.imageResource = new UserProductImageResource(aUserProductImage, aApplication);

        return result;
    }
}

public class UserProductImageResource implements ApplicationResource, Resource {
private final UserProductImage userProductImage;
private final Application application;

public UserProductImageResource(final UserProductImage aUserProductImage,
                                final Application aApplication) {
    userProductImage = aUserProductImage;
    application = aApplication;
}

public String getMIMEType() {
    return userProductImage.getMimeType();
}

public DownloadStream getStream() {
    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(userProductImage
            .getImageData());
    final DownloadStream downloadStream = new DownloadStream(byteArrayInputStream,
            userProductImage.getMimeType(), userProductImage.getFileName());
    return downloadStream;
}

public Application getApplication() {
    return application;
}

public String getFilename() {
    return userProductImage.getFileName();
}

public long getCacheTime() {
    return 0;
}

public int getBufferSize() {
    return userProductImage.getImageData().length;
}

}

В результате этих операций я получаю таблицу, показанную ниже.

Скриншот

Как я могу изменить код, чтобы свойство imageResource отображается как изображение?

Обновление 1 (16.10.2014 22:21 мск):

Я реализовал класс ImageColumnGenerator как предложено Zigac.

public class ImageColumnGenerator implements Table.ColumnGenerator {
    private static final Logger LOGGER = LoggerFactory.getLogger(ImageColumnGenerator.class);

    public final static String IMAGE_FIELD = "image";

    public Object generateCell(final Table aTable, final Object aItemId, final Object aColumnId) {
        if (!IMAGE_FIELD.equals(aColumnId))
        {
             return null;
        }
        final BeanItem<UserProductImageBean> beanItem = (BeanItem<UserProductImageBean>)
                aTable.getItem(aItemId);

        final UserProductImageResource imageResource = beanItem.getBean().getImageResource();

        LOGGER.debug("imageResource: " + imageResource);

        final Embedded embedded = new Embedded("", imageResource);


        return embedded;
    }
}

Когда я создаю таблицу, я указываю генератор столбцов следующим образом:

productImagesTable.addGeneratedColumn(ImageColumnGenerator.IMAGE_FIELD,
        new ImageColumnGenerator());

Но когда я открываю страницу, я получаю следующее исключение.

java.lang.NullPointerException: Parameters must be non-null strings
at com.vaadin.terminal.gwt.server.JsonPaintTarget.addAttribute(JsonPaintTarget.java:420)
at com.vaadin.terminal.gwt.server.JsonPaintTarget.addAttribute(JsonPaintTarget.java:387)
at com.vaadin.ui.Embedded.paintContent(Embedded.java:142)
at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:781)
at com.vaadin.ui.Table.paintRow(Table.java:3356)
at com.vaadin.ui.Table.paintRows(Table.java:3169)
at com.vaadin.ui.Table.paintContent(Table.java:2776)
at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:781)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.writeUidlResponce(AbstractCommunicationManager.java:1044)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.paintAfterVariableChanges(AbstractCommunicationManager.java:925)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:792)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:318)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Обновление 2 (17.10.2014 12:16): мне удалось исправить эту проблему (NPE), но теперь у меня есть еще одна проблема - см. Этот вопрос.

Обновление 3 (19.10.2014 00:02 MSK): Так выглядит таблица, когда окно открывается впервые.

До

Когда список изображений получен от веб-службы, таблица сжимается, поэтому изображения не отображаются.

После

Следующий код выполняется для обновления таблицы.

    productImageData.removeAllItems();

    for (final UserProductImage curImage : userProductImages)
    {
        productImageData.addBean(UserProductImageBean.create(curImage,
                InwtApplication.getInstance(), this));
    }

    productImagesTable.setColumnWidth(ImageColumnGenerator.IMAGE_FIELD, 1000);
    productImagesTable.setWidth("100%");
    productImagesTable.requestRepaint();

1 ответ

Решение

Вы можете использовать макет в качестве типа для столбца "Контейнер" и создать макет с изображением (стандартный способ добавления изображения vaadin: vaadin.com/book/vaadin6/-/page/components.embedded.html) внутри него... вы Вам останется только построить макеты с изображением внутри.

Чтобы иметь правильный размер таблицы, не устанавливайте ширину столбца, а только размер макета, таблица будет сама себя масштабировать по размеру содержимого.

D.

Другие вопросы по тегам