java - 图像字段作为 Vaadin7 中 FieldGroup 的一部分

标签 java image vaadin vaadin7

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

我有一个 Pojo,其属性为 com.vaadin.ui.Image 类型以及其他字符串和整数值。

public Image getImage() {
    return image;
}

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

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

我尝试过使用EasyUploads addon为此,通过拦截 FieldGroup 的构建方法并将 Image 字段指定为 org.vaadin.easyuploads.UploadField

类型

像这样;

 @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 中使用图像作为 FieldGroup 的一部分?

最佳答案

我建议用简单的 byte[] 替换 Pojo 中的 Image 实例,因为查看 UploadField 代码,我看不到任何转换上传结果的自然方法(可以是 byte[]或文件实例)到其他东西,使用 FieldGroup 就像你问的那样。

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

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

  1. 创建一个自定义 FieldGroupFieldFactory,如果您想绑定(bind)到 byte[] 属性,它将创建一个 UploadField + 为 UploadField 上传完成时传递一个 ValueChangeListener:

    公共(public)类 ImageEnhancedFieldFactory 扩展了 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);
    

注意:有必要将缓存时间设置为 0,以防止浏览器缓存资源(请参阅生成和重新加载图像部分中的 https://vaadin.com/book/vaadin7/-/page/components.embedded.html )

3.创建FieldGroup(使用新的FieldGroupFieldFactory集)并绑定(bind)到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"));

我在组件要点上留下了一个片段,您可以将其粘贴到 UI 中并在需要时使用 ( https://gist.github.com/gabrielruiu/9953279 )

关于java - 图像字段作为 Vaadin7 中 FieldGroup 的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22821073/

相关文章:

Java 基本笔画 "Fuzzy"

php - 带有 php 循环的 CSS onmouseover 画廊

java - Vaadin 主题 : java. lang.Exception:Mixin 定义:未找到 valo

java - 使用新 fragment 动态更新 ViewPager

java - HashSet 中有多少个唯一对象以及使用哪个方法检查唯一性等于或 hashCode

c# - 将图像嵌入到自己的文件中

css - 如何对齐/移动 Vaadin 按钮

java - XML 作为 Vaadin 树的数据源

java - Spring部署设置openshift

ios - 如何使图像仅在 iPhone 6/6s 上可见