Created
November 9, 2023 09:42
-
-
Save TatuLund/986114a82078e7228b1c37ba4b07f94d to your computer and use it in GitHub Desktop.
Vaadin 14/23/24 Upload component does not yet have good Java API for removing files server side. This example shows a workaround how to detect file remove button event and use it to remove matching component according to file na,e.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.application.views; | |
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.util.Iterator; | |
import javax.imageio.ImageIO; | |
import javax.imageio.ImageReader; | |
import javax.imageio.stream.ImageInputStream; | |
import org.apache.commons.io.IOUtils; | |
import com.vaadin.flow.component.ClientCallable; | |
import com.vaadin.flow.component.Component; | |
import com.vaadin.flow.component.ComponentUtil; | |
import com.vaadin.flow.component.html.Div; | |
import com.vaadin.flow.component.html.Image; | |
import com.vaadin.flow.component.notification.Notification; | |
import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |
import com.vaadin.flow.component.upload.Upload; | |
import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer; | |
import com.vaadin.flow.router.Route; | |
import com.vaadin.flow.server.StreamResource; | |
import elemental.json.JsonValue; | |
@Route(value = "upload", layout = MainLayout.class) | |
public class UploadView extends VerticalLayout { | |
private Div output; | |
// This is called from JavaScript event listener, compare file name | |
// to piggy bagged file names and remove if match | |
@ClientCallable | |
public void fileRemove(JsonValue event) { | |
output.getChildren() | |
.filter(component -> event.toJson().contains( | |
(String) ComponentUtil.getData(component, "name"))) | |
.findFirst().ifPresent(match -> output.remove(match)); | |
} | |
public UploadView() { | |
output = new Div(); | |
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer(); | |
Upload upload = new Upload(buffer); | |
upload.setSizeFull(); | |
upload.addFileRejectedListener(event -> { | |
Notification.show(event.getErrorMessage()); | |
}); | |
upload.setAcceptedFileTypes("image/jpeg"); | |
upload.addSucceededListener(event -> { | |
Component component = createComponent(event.getFileName(), | |
buffer.getInputStream(event.getFileName())); | |
output.add(component); | |
}); | |
// using | |
// reg = upload.getElement().addEventListener("file-remove" ... | |
// reg.addEventData("event.detail"); | |
// does not work here, as the file.name is not included in event data | |
// thus we need to wire event listener in JavaScript and call client | |
// callable method | |
upload.getElement().executeJs( | |
"this.addEventListener('file-remove', (e) => $0.$server.fileRemove(e.detail.file.name));", | |
getElement()); | |
add(upload, output); | |
} | |
private Component createComponent(String fileName, InputStream stream) { | |
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("300px"); | |
} finally { | |
reader.dispose(); | |
} | |
} | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
// Piggy bag name of the file to the component | |
ComponentUtil.setData(image, "name", fileName); | |
return image; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment