图像字段作为Vaadin 7中字段组的一部分

时间:2014-04-02 19:23:11

标签: java image vaadin vaadin7

我要求将图像显示为FieldGroup的一部分。这是针对图像在网页上显示为正常的功能,当处于编辑模式时,我需要通过提供“上传”来编辑此图像值。选项。

我有一个Pojo,其属性类型为com.vaadin.ui.Image,还有其他String和Integer值。

public Image getImage() {
    return image;
}

public void setImage(Image image) {
    this.image = image;
}

我需要将此Image用作普通表单元素,例如,当我编辑表单时,我有一个可编辑的TextField来输入String值并更改它,就像我一样打算显示一个上传按钮,我可以选择替换现有图像。

我已尝试通过截取FieldGroup的构建方法并指定类型为org.vaadin.easyuploads.UploadField

的图像字段来为此目的使用EasyUploads addon

喜欢这个;

 @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected <T extends Field> T build(String caption, Class<?> dataType,
            Class<T> fieldType) throws BindException {

        T field = super.build(caption, dataType, fieldType);
        if (caption.equalsIgnoreCase("image")) {
            final UploadField imageField = new UploadField() {
                @Override
                protected void updateDisplay() {
                    final byte[] pngData = (byte[]) getValue();
                    String filename = getLastFileName();
                    String mimeType = getLastMimeType();
                    long filesize = getLastFileSize();
                    if (mimeType.equals("image/jpeg")) {
                        StreamSource imagesource = new ImageSource(pngData);
                        StreamResource resource = new StreamResource(
                                imagesource, "Uploaded File");

                        Embedded embedded = new Embedded("Image:" + filename
                                + "(" + filesize + " bytes)", resource);
                        getRootLayout().addComponent(embedded);
                    } else {
                        super.updateDisplay();
                    }
                }
            };
            imageField.setFieldType(FieldType.BYTE_ARRAY);
...

然而,这无法显示已经可用的图像,堆栈跟踪错误:

Caused by: java.lang.IllegalArgumentException: Property type class com.vaadin.ui.Image is not compatible with UploadField
    at org.vaadin.easyuploads.UploadField.setPropertyDataSource(UploadField.java:1021)
    at com.vaadin.data.fieldgroup.FieldGroup.bind(FieldGroup.java:265)
    at com.vaadin.data.fieldgroup.BeanFieldGroup.bind(BeanFieldGroup.java:167)
    at com.vaadin.data.fieldgroup.FieldGroup.setItemDataSource(FieldGroup.java:106)
    at com.vaadin.data.fieldgroup.BeanFieldGroup.setItemDataSource(BeanFieldGroup.java:142)

在vaadin 7中有没有更简洁的方法将Image用作FieldGroup的一部分?

1 个答案:

答案 0 :(得分:4)

我建议用一个简单的byte []替换你的Pojo Image实例,因为查看UploadField代码,我看不到任何自然的转换结果来自上传(这是一个byte []或者像其他人一样使用FieldGroup,就像你问的那样。

如果您查看AbstractField.getValue(),您将看到模型值最终通过一个可设置的转换器,在这种情况下通常会帮助您(请参阅com.vaadin.data.util.converter.Converter) 。但是如果你想将一个图像bean绑定到FieldGroup,我认为你几乎被迫使用byte []。

无论如何,如果您 DO 替换为byte [],以下步骤将对您有所帮助:

  1. 创建一个自定义FieldGroupFieldFactory,如果要绑定到byte []属性,将创建一个UploadField +为UploadField传递一个ValueChangeListener完成上传:

    public class ImageEnhancedFieldFactory extends DefaultFieldGroupFieldFactory {

    private Property.ValueChangeListener fileUploadedListener;
    
    private ImageEnhancedFieldFactory(Property.ValueChangeListener fileUploadedListener) {
        this.fileUploadedListener = fileUploadedListener;
    }
    
    @Override
    public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
        if (byte[].class.equals(type)) {
            UploadField uploadField = new UploadField(UploadField.StorageMode.MEMORY);
            uploadField.setFieldType(UploadField.FieldType.BYTE_ARRAY);
            uploadField.setButtonCaption("Change image");
            uploadField.addListener(fileUploadedListener);
            return (T) uploadField;
        }
        return super.createField(type, fieldType);
    }
    

    }

  2. 创建一个Image实例,显示pojo中byte []的内容:

        final ImagePojo imagePojo = new ImagePojo();
    imagePojo.setName("superman");
    imagePojo.setImageContent(new byte[0]);
    
    BeanItem<ImagePojo> item = new BeanItem<ImagePojo>(imagePojo);
    
    
    final StreamResource imageResource = new StreamResource(new StreamResource.StreamSource() {
        @Override
        public InputStream getStream() {
            return new ByteArrayInputStream(imagePojo.getImageContent());
        }
    }, "myimage");
    imageResource.setCacheTime(0);
    
    final Image image = new Image("Image", imageResource);
    addComponent(image);
    
  3. 注意:必须将缓存时间设置为0,以防止浏览器缓存资源(请参阅生成和重新加载图像

    3.创建FieldGroup(使用新的FieldGroupFieldFactory集)并绑定到pojo的属性,包括包含图像内容的那个(byte []):

    FieldGroup fieldGroup = new FieldGroup(item);
        fieldGroup.setFieldFactory(new ImageEnhancedFieldFactory(new Property.ValueChangeListener() {
            @Override
            public void valueChange(Property.ValueChangeEvent event) {
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                String filename = "myfilename-" + df.format(new Date()) + ".jpg";
                imagePojo.setImageContent((byte[])event.getProperty().getValue());
                image.markAsDirty();
                imageResource.setFilename(filename);
            }
        }));
    
        addComponent(fieldGroup.buildAndBind("Image name", "name"));
        addComponent(fieldGroup.buildAndBind("Image content", "imageContent"));
    

    我在一个组件的Gist上留下了一个片段,您可以将其粘贴到UI中并在需要时播放(https://vaadin.com/book/vaadin7/-/page/components.embedded.html