vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
616 stars 169 forks source link

Picture does not show when I upload it #8301

Closed DanielMartensson closed 4 years ago

DanielMartensson commented 4 years ago

Description of the bug

When I upload the picture, the picture does not show up.

Minimal reproducible example

MainView.

@Route("")
@Viewport("width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes, viewport-fit=cover")
@PreserveOnRefresh
public class MainView extends AppLayout {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public MainView() {

        // Get the components
        VerticalLayout subjectCounterExportButtonUpload = new LoadExportTemplate().getSubjectCounterExportButtonUploaders();

        setContent(subjectCounterExportButtonUpload);

    }
}
@Data
public class LoadExportTemplate {

    private VerticalLayout subjectCounterExportButtonUploaders;
    public LoadExportTemplate() {

        subjectCounterExportButtonUploaders = new VerticalLayout();
        Upload pictureUpload = new PictureUpload().getUpload();
        Div output = new PictureUpload().getOutput();
        subjectCounterExportButtonUploaders.add(pictureUpload, output);

    }
}
public class PictureUpload {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private @Getter Upload upload;
    private @Getter Div output;

    public PictureUpload() {
        // Add picture uploader
        upload = new Upload();
        output = new Div();
        addPictureUploader();
    }

    private void addPictureUploader() {

        MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
        // Button is removed with style module, see styles.html
        upload = new Upload(buffer);
        upload.setSizeFull();
        upload.addStartedListener(event -> {
            upload.getElement().getPropertyNames().forEach(prop -> System.out.println(prop+" "+upload.getElement().getProperty(prop)));
        });
        upload.addFileRejectedListener(event -> {
            Notification.show(event.getErrorMessage());
        });
        upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");

        upload.addSucceededListener(event -> {
            Component component = createComponent(event.getMIMEType(), event.getFileName(), buffer.getInputStream(event.getFileName()));
            showOutput(event.getFileName(), component, output);

        }); 

        upload.addFailedListener(event -> {
            Notification.show("Failed to load file: "+event.getFileName()).addThemeVariants(NotificationVariant.LUMO_ERROR);
            upload.getElement().setPropertyJson("files", Json.createArray());
        });

    }

    private Component createComponent(String mimeType, String fileName,
            InputStream stream) {
        if (mimeType.startsWith("text")) {
            String text = "";
            try {
                text = IOUtils.toString(stream, "UTF-8");
            } catch (IOException e) {
                text = "exception reading stream";
            }
            return new Text(text);
        } else if (mimeType.startsWith("image")) {
            Image image = new Image();
            try {

                byte[] bytes = IOUtils.toByteArray(stream);
                image.getElement().setAttribute("src", new StreamResource(
                        fileName, () -> new ByteArrayInputStream(bytes)));
                try (ImageInputStream in = ImageIO.createImageInputStream(
                        new ByteArrayInputStream(bytes))) {
                    final Iterator<ImageReader> readers = ImageIO
                            .getImageReaders(in);
                    if (readers.hasNext()) {
                        ImageReader reader = readers.next();
                        try {
                            reader.setInput(in);
                            image.setWidth(reader.getWidth(0) + "px");
                            image.setHeight(reader.getHeight(0) + "px");
                        } finally {
                            reader.dispose();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            return image;
        }
        Div content = new Div();
        String text = String.format("Mime type: '%s'\nSHA-256 hash: '%s'", mimeType, MessageDigestUtil.sha256(stream.toString()));
        content.setText(text);
        return new Div();
    }

    private void showOutput(String text, Component content, HasComponents outputContainer) {
        HtmlComponent p = new HtmlComponent(Tag.P);
        p.getElement().setText(text);
        outputContainer.add(p);
        outputContainer.add(content);
    }
}

Expected behavior

I picture should show up.

Actual behavior

Picture does not show up when I upload it.

Versions:

- Vaadin 14.1.27
- Java version 11.04:
- Lubuntu 20.04:
- Firefox:
- Spring Boot:
- Eclipse IDE 2020-03:

Picture of the problem

https://i.ibb.co/60r2Wrr/S-lection-008.png

knoobie commented 4 years ago

I haven't tested your code but this looks wrong. Why do you create two instances?

Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();
DanielMartensson commented 4 years ago

I haven't tested your code but this looks wrong. Why do you create two instances?

Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();

Because I want to get the output and the picture uploader. My code is far more complex and I posted the minimum code.

knoobie commented 4 years ago

Your code works 100% for me - except that I had to change

Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();

to

PictureUpload upload = new PictureUpload();
layout.add(upload.getUpload());
layout.add(upload.getOutput());

image

Java 8 / Vaadin 14.1.27

DanielMartensson commented 4 years ago

Your code works 100% for me - except that I had to change

Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();

to

PictureUpload upload = new PictureUpload();
layout.add(upload.getUpload());
layout.add(upload.getOutput());

image

Java 8 / Vaadin 14.1.27

Does not work for me.

```
     public LoadExportTemplate() {

    subjectCounterExportButtonUploaders = new VerticalLayout();
    Upload pictureUpload = new PictureUpload().getUpload();
    Div output = new PictureUpload().getOutput();
    subjectCounterExportButtonUploaders.add(pictureUpload);
    subjectCounterExportButtonUploaders.add(output);

}
knoobie commented 4 years ago

It can't work, because you have two different instances of PictureUpload. Replace your code with the following:

    subjectCounterExportButtonUploaders = new VerticalLayout();
    PictureUpload pictureUpload = new PictureUpload();
    subjectCounterExportButtonUploaders.add(pictureUpload.getUpload());
    subjectCounterExportButtonUploaders.add(pictureUpload.getOutput());
DanielMartensson commented 4 years ago

It can't work, because you have two different instances of PictureUpload. Replace your code with the following:

  subjectCounterExportButtonUploaders = new VerticalLayout();
  PictureUpload pictureUpload = new PictureUpload();
  subjectCounterExportButtonUploaders.add(pictureUpload.getUpload());
  subjectCounterExportButtonUploaders.add(pictureUpload.getOutput());

Now I see! Thank you! It works now!