Java tutorial
/******************************************************************************* * Copyright 2016 Antoine Nicolas SAMAHA * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ package com.foc.vaadin.gui.components; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Date; import java.text.SimpleDateFormat; import javax.imageio.ImageIO; import org.xml.sax.Attributes; import com.foc.ConfigInfo; import com.foc.Globals; import com.foc.desc.FocObject; import com.foc.property.FBlobMediumProperty; import com.foc.property.FCloudStorageProperty; import com.foc.property.FImageProperty; import com.foc.property.FProperty; import com.foc.util.Utils; import com.foc.vaadin.FocWebApplication; import com.foc.vaadin.gui.FVIconFactory; import com.foc.vaadin.gui.FocXMLGuiComponent; import com.foc.vaadin.gui.FocXMLGuiComponentStatic; import com.foc.vaadin.gui.components.upload.FVImageReceiver; import com.foc.vaadin.gui.components.upload.FVUpload_Image; import com.foc.vaadin.gui.layouts.FVVerticalLayout; import com.foc.vaadin.gui.xmlForm.FXML; import com.foc.vaadin.gui.xmlForm.FocXMLLayout; import com.vaadin.server.ConnectorResource; import com.vaadin.server.DownloadStream; import com.vaadin.server.FileDownloader; import com.vaadin.server.Resource; import com.vaadin.server.StreamResource; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Component; import com.vaadin.ui.Field; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Image; import com.vaadin.ui.UI; import com.vaadin.ui.Upload.SucceededEvent; import com.vaadin.util.FileTypeResolver; @SuppressWarnings("serial") public class FVImageField extends FVVerticalLayout implements FocXMLGuiComponent, FVImageReceiver { private Image embedded = null; private FImageProperty imageProperty = null; private FCloudStorageProperty cloudStorageProperty = null; private FBlobMediumProperty blobMediumProperty = null; private GenericFileResource resource = null; private boolean isImage = false; private boolean editable = true; private double originalWidth = -1; private double originalHeight = -1; private HorizontalLayout imageControlLayout;//Should not be set =null because the super call is setting them and the init after the super call can put them to null private Attributes attributes = null; private Button downloadButton = null; public FVImageField(FProperty property, Attributes attributes) { super(); setSpacing(true); setAttributes(attributes); addStyleName("foc-ImageField"); setProperty(property); // setSpacing(false); } public void dispose() { super.dispose(); imageProperty = null; cloudStorageProperty = null; blobMediumProperty = null; if (downloadButton != null) { // downloadButton.dispose(); downloadButton = null; } attributes = null; } public void setAttributes(Attributes attributes) { if (attributes != null) { this.attributes = attributes; String width = attributes.getValue(FXML.ATT_WIDTH); String height = attributes.getValue(FXML.ATT_HEIGHT); if (getEmbedded() != null && width != null && height != null) { setWidth(width); setHeight(height); try { width = width.substring(0, width.indexOf("px")); height = height.substring(0, height.indexOf("px")); int widthInt = Integer.valueOf(width); int heightInt = Integer.valueOf(height); double ratio = getRatio(getEmbedded(), widthInt, heightInt); int newWidthInt = (int) (originalWidth * ratio); int newHeightInt = (int) (originalHeight * ratio); String newWidth = Integer.toString(newWidthInt); String newHeight = Integer.toString(newHeightInt); getEmbedded().setWidth(newWidth + "px"); getEmbedded().setHeight(newHeight + "px"); int fieldWidth = newWidthInt; int fieldHeight = newHeightInt; if (isEditable()) { fieldHeight += 50;//To keep some space for the buttons } setWidth(Integer.toString(fieldWidth) + "px"); setHeight(Integer.toString(fieldHeight) + "px"); } catch (Exception e) { Globals.logException(e); } } } FocXMLGuiComponentStatic.setCaptionMargin_Zero(this); if (getDelegate() != null) { setEditable(getDelegate().isEditable()); } } public Image resizeImage(Image image, int maxWidth, int maxHeight) { if (image != null) { double ratio = getRatio(image, maxWidth, maxHeight); String newHeight = Integer.toString((int) (image.getHeight() * ratio)); String newWidth = Integer.toString((int) (image.getWidth() * ratio)); image.setWidth(newWidth + "px"); image.setHeight(newHeight + "px"); setWidth(newWidth + "px"); setHeight(newHeight + "px"); } return image; } private double getRatio(Image embedded, int maxWidth, int maxHeight) { double ratio = 1; double ratioWidth = 0; double ratioHeight = 0; if (originalWidth != 0) { ratioWidth = maxWidth / originalWidth; } if (originalHeight != 0) { ratioHeight = maxHeight / originalHeight; } if (ratioWidth != 0 && ratioHeight != 0) { ratio = ratioHeight; if (ratioWidth < ratio) ratio = ratioWidth; if (ratio > 1) ratio = 1;//Do not expand } return ratio; } public Attributes getAttributes() { return attributes; } private void setEmbedded(Image embedded) { this.embedded = embedded; } public Image getEmbedded() { return embedded; } private void adjustDownloadButtonVisibility(FProperty property) { if (property != null && property.getFocField() != null) { boolean visible = false; if (property instanceof FCloudStorageProperty) { visible = !property.getFocObject().isCreated() && ((FCloudStorageProperty) property).doesFileExist(); } else if (property instanceof FImageProperty) { visible = true; } else if (property instanceof FBlobMediumProperty) { visible = false; } if (downloadButton != null) downloadButton.setVisible(visible); } } public void setProperty(FProperty property) { if (property != null && property.getFocField() != null) { if (property instanceof FCloudStorageProperty) { setCloudStorageProperty((FCloudStorageProperty) property); } else if (property instanceof FImageProperty) { this.setImageProperty((FImageProperty) property); } else if (property instanceof FBlobMediumProperty) { this.setBlobMediumProperty((FBlobMediumProperty) property); } } adjustDownloadButtonVisibility(property); if (resource != null) { resource.setProperty(property); } boolean showImage = true; String showImgStr = getAttributes() != null ? getAttributes().getValue(FXML.ATT_SHOW_IMAGE) : "true"; if (showImgStr != null && (showImgStr.trim().toLowerCase().equals("false") || showImgStr.trim().toLowerCase().equals("0"))) { showImage = false; } if (showImage) { embedded = new Image(); embedded.setImmediate(false); setEmbedded(embedded); boolean error = refreshImageFromProperty(); setIsImage(!error); addComponentAsFirst(embedded); setExpandRatio(embedded, 1); reactToEditable(); } } public BufferedImage getBufferedImage() { BufferedImage result = null; if (getCloudStorageProperty() != null) { result = getCloudStorageProperty().getBufferedImage(); } else if (getImageProperty() != null) { result = getImageProperty().getImageValue(); } return result; } @Override public String getXMLType() { return FXML.TAG_FIELD; } @Override public Field getFormField() { return null; } @Override public FProperty getFocData() { FProperty prop = null; if (getCloudStorageProperty() != null) { prop = getCloudStorageProperty(); } else if (getImageProperty() != null) { prop = getImageProperty(); } else if (getBlobMediumProperty() != null) { prop = getBlobMediumProperty(); } return prop; } public FProperty getFocProperty() { FProperty porp = null; if (cloudStorageProperty != null) { porp = cloudStorageProperty; } else if (imageProperty != null) { porp = imageProperty; } return porp; } public FocObject getFocObject() { FocObject focObject = null; FProperty prop = getFocProperty(); if (prop != null) { focObject = prop.getFocObject(); } return focObject; } @Override public void imageReceived(SucceededEvent event, InputStream image) { if (cloudStorageProperty != null) { if (event != null && !Utils.isStringEmpty(event.getFilename())) { cloudStorageProperty.setFileNameInProperty(event.getFilename()); cloudStorageProperty.generateKey(); } cloudStorageProperty.setObject(image); } else { BufferedImage bufferedImage = null; try { bufferedImage = ImageIO.read(image); } catch (IOException e) { e.printStackTrace(); } //This is because if (imageProperty != null) { FocObject focObject = imageProperty.getFocObject(); if (focObject != null && focObject.isCreated()) { focObject.validate(true); } //BAntoineS-20151110 imageProperty.setImageValue(bufferedImage); //EAntoineS-20151110 } } refreshImageFromProperty(); adjustDownloadButtonVisibility(cloudStorageProperty != null ? cloudStorageProperty : imageProperty); } public boolean saveObjectBeforeUploadIfCreated() { boolean error = false; //If Object is created we need to insert it first FocObject focObject = getFocObject(); if (focObject != null && focObject.isCreated()) { error = true; Component comp = this; while (comp != null && comp.getParent() != null) { comp = comp.getParent(); if (comp instanceof FocXMLLayout) { FocXMLLayout xmlLay = (FocXMLLayout) comp; xmlLay.copyGuiToMemory(); if (xmlLay.getValidationLayout() != null) { if (!xmlLay.getValidationLayout().commit()) { error = false; break; } } } } //If Still created we try directly saving if (!error && focObject.isCreated()) focObject.validate(true); } return error; } public boolean refreshImageFromProperty() { BufferedImage photo = getBufferedImage(); boolean error = photo == null; if (!error) { originalHeight = photo.getHeight(); originalWidth = photo.getWidth(); setAttributes(getAttributes()); StreamResource.StreamSource streamSource = new StreamResource.StreamSource() { public InputStream getStream() { try { /* Write the image to a buffer. */ ByteArrayOutputStream imagebuffer = new ByteArrayOutputStream(); ImageIO.write(getBufferedImage()/*Globals.getApp().getCompany().getLogo()*/, "png", imagebuffer); /* Return a stream from the buffer. */ return new ByteArrayInputStream(imagebuffer.toByteArray()); } catch (IOException e) { Globals.logException(e); return null; } } }; UI application = FocWebApplication.getInstanceForThread(); if (application != null) { StreamResource streamResource = new StreamResource(streamSource, ""); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String timestamp = df.format(new Date(System.currentTimeMillis())); streamResource.setFilename("FileName-" + timestamp + ".jpg"); if (embedded != null) { embedded.setSource(streamResource); } } } return error; } public Button getDownloadButton() { return downloadButton; } public boolean isEditable() { return editable; } public void setEditable(boolean editable) { this.editable = editable; reactToEditable(); } @Override public boolean copyGuiToMemory() { return false; } @Override public void copyMemoryToGui() { } public void reactToEditable() { if (isEditable()) { if (imageControlLayout != null) { imageControlLayout.setVisible(true); } else { imageControlLayout = new HorizontalLayout(); imageControlLayout.setSpacing(true); imageControlLayout.setWidth("100%"); imageControlLayout.setHeight("-1px"); addComponent(imageControlLayout); setComponentAlignment(imageControlLayout, Alignment.TOP_RIGHT); if (isEditable()) { FVUpload_Image uploader = new FVUpload_Image(); uploader.setWidth("100px"); imageControlLayout.addComponent(uploader); imageControlLayout.setComponentAlignment(uploader, Alignment.TOP_RIGHT); uploader.setImageReceiver(this); downloadButton = new Button("Download");//, FVIconFactory.getInstance().getFVIcon_24(FVIconFactory.ICON_DOWNLOAD)); if (ConfigInfo.isArabic()) { downloadButton.setCaption("");//To hide the default ugly button we should set this to null } // downloadButton.setIcon(FontAwesome.DOWNLOAD); downloadButton.setWidth("100px"); // downloadButton.setCaption(null); // downloadButton.setStyleName(BaseTheme.BUTTON_LINK); downloadButton.addStyleName(FocXMLGuiComponentStatic.STYLE_NO_PRINT); downloadButton.addStyleName(FocXMLGuiComponentStatic.STYLE_HAND_POINTER_ON_HOVER); imageControlLayout.addComponent(downloadButton); imageControlLayout.setComponentAlignment(downloadButton, Alignment.TOP_LEFT); resource = new GenericFileResource(getFocData()); FileDownloader downloader = new FileDownloader(resource); downloader.extend(downloadButton); } } } else { if (imageControlLayout != null) imageControlLayout.setVisible(false); } } public FCloudStorageProperty getCloudStorageProperty() { return cloudStorageProperty; } public void setCloudStorageProperty(FCloudStorageProperty cloudStorageProperty) { this.cloudStorageProperty = cloudStorageProperty; } public FImageProperty getImageProperty() { return imageProperty; } public void setImageProperty(FImageProperty imageProperty) { this.imageProperty = imageProperty; } public FBlobMediumProperty getBlobMediumProperty() { return blobMediumProperty; } public void setBlobMediumProperty(FBlobMediumProperty blobMediumProperty) { this.blobMediumProperty = blobMediumProperty; } public boolean isImage() { return isImage; } public void setIsImage(boolean isImage) { this.isImage = isImage; } public Resource getResourceAndSetIcon() { Resource resource = null; if (getCloudStorageProperty().getFileName().endsWith(".xls") || getCloudStorageProperty().getFileName().endsWith(".xlsx") || getCloudStorageProperty().getFileName().endsWith(".csv")) { resource = FVIconFactory.getInstance().getFVIcon_24(FVIconFactory.ICON_EXCEL); } else if (getCloudStorageProperty().getFileName().endsWith(".doc") || getCloudStorageProperty().getFileName().endsWith(".docx")) { resource = FVIconFactory.getInstance().getFVIcon_24(FVIconFactory.ICON_WORD); } else if (getCloudStorageProperty().getFileName().endsWith(".ppt") || getCloudStorageProperty().getFileName().endsWith(".pptx")) { resource = FVIconFactory.getInstance().getFVIcon_24(FVIconFactory.ICON_PPT); } else if (getCloudStorageProperty().getFileName().endsWith(".pdf")) { resource = FVIconFactory.getInstance().getFVIcon_24(FVIconFactory.ICON_ADOBE); } else { resource = FVIconFactory.getInstance().getFVIcon(FVIconFactory.ICON_NOTE); } return resource; } public class GenericFileResource implements ConnectorResource {//FileResource { private FProperty property = null; // private ByteArrayInputStream bais = null; // private InputStream inputStream = null; // private String fileName = null; // public GenericFileResource(InputStream inputStream, String fileName){ // this.inputStream = inputStream; // this.fileName = fileName; // } public GenericFileResource(FProperty property) { this.property = property; } public void dispose() { property = null; // if(bais != null){ // try{ // bais.close(); // }catch (IOException e){ // Globals.logException(e); // } // bais = null; // } } @Override public DownloadStream getStream() { DownloadStream downloadStream = null; ByteArrayInputStream bais = null; Object value = property.getValue(); if (value instanceof InputStream) { InputStream inputStream = (InputStream) value; if (inputStream instanceof FileInputStream) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int byt = 0; while ((byt = inputStream.read()) != -1) { byteArrayOutputStream.write(byt); } inputStream.close(); bais = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); } catch (Exception ex) { ex.printStackTrace(); } } else { bais = (ByteArrayInputStream) inputStream; } } else if (value instanceof BufferedImage) { ByteArrayOutputStream imagebuffer = new ByteArrayOutputStream(); try { ImageIO.write((BufferedImage) value, "png", imagebuffer); } catch (IOException e) { Globals.logExceptionWithoutPopup(e); } /* Return a stream from the buffer. */ bais = new ByteArrayInputStream(imagebuffer.toByteArray()); // }else if(getBlobMediumProperty() != null){ // inputStream = (InputStream) getBlobMediumProperty().getValue(); } if (bais != null) { String fileName = getFilename(); downloadStream = new DownloadStream(bais, "application/x-unknown", fileName); downloadStream.setParameter("Content-Disposition", "attachment; filename=" + DownloadStream.getContentDispositionFilename(fileName)); downloadStream.setCacheTime(0); } return downloadStream; } @Override public String getMIMEType() { return FileTypeResolver.getMIMEType(getFilename()); } @Override public String getFilename() { String fileName = ""; if (property != null) { if (property instanceof FCloudStorageProperty) { fileName = ((FCloudStorageProperty) property).getFileName(); } else if (property instanceof FImageProperty) { fileName = "Image.png"; } } return fileName; } public FProperty getProperty() { return property; } public void setProperty(FProperty property) { this.property = property; } } }