我需要将图像显示为 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[],以下步骤将对您有所帮助:
创建一个自定义 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); }
}
创建一个 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/