From 3c7f2da752c3a660a0e21bd4c42fe93a5e965996 Mon Sep 17 00:00:00 2001 From: delvh Date: Sat, 10 Oct 2020 14:31:10 +0200 Subject: [PATCH] Add image caching --- .../envoy/client/ui/controller/ChatScene.java | 10 ++-- .../main/java/envoy/client/util/IconUtil.java | 46 +++++++++++++++---- client/src/main/resources/fxml/ChatScene.fxml | 2 +- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index da4323e..c2b0ef1 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -132,7 +132,6 @@ public final class ChatScene implements EventListener, Restorable { private Chat currentChat; private FilteredList chats; - private boolean recording; private Attachment pendingAttachment; private boolean postingPermanentlyDisabled; private boolean isCustomAttachmentImage; @@ -354,7 +353,8 @@ public final class ChatScene implements EventListener, Restorable { // Discard the pending attachment if (recorder.isRecording()) { recorder.cancel(); - recording = false; + voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE))); + voiceButton.setText(null); } pendingAttachment = null; updateAttachmentView(false); @@ -414,18 +414,16 @@ public final class ChatScene implements EventListener, Restorable { private void voiceButtonClicked() { new Thread(() -> { try { - if (!recording) { - recording = true; + if (!recorder.isRecording()) { Platform.runLater(() -> { voiceButton.setText("Recording"); voiceButton.setGraphic(new ImageView(IconUtil.loadIcon("microphone_recording", DEFAULT_ICON_SIZE))); }); recorder.start(); } else { - pendingAttachment = new Attachment(recorder.finish(), "Voice_recording_" + pendingAttachment = new Attachment(recorder.finish(), "Voice_recording_" + DateTimeFormatter.ofPattern("yyyy_MM_dd-HH_mm_ss").format(LocalDateTime.now()) + "." + AudioRecorder.FILE_FORMAT, AttachmentType.VOICE); - recording = false; Platform.runLater(() -> { voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE))); voiceButton.setText(null); diff --git a/client/src/main/java/envoy/client/util/IconUtil.java b/client/src/main/java/envoy/client/util/IconUtil.java index 42a8554..39dce33 100644 --- a/client/src/main/java/envoy/client/util/IconUtil.java +++ b/client/src/main/java/envoy/client/util/IconUtil.java @@ -21,8 +21,11 @@ import envoy.util.EnvoyLog; */ public final class IconUtil { - private IconUtil() {} + private static final HashMap cache = new HashMap<>(); + private static final HashMap awtCache = new HashMap<>(); + private IconUtil() {} + /** * Loads an image from the resource folder. * @@ -30,7 +33,14 @@ public final class IconUtil { * @return the loaded image * @since Envoy Client v0.1-beta */ - public static Image load(String path) { return new Image(IconUtil.class.getResource(path).toExternalForm()); } + public static Image load(String path) { + if (cache.containsKey(path)) return cache.get(path); + else { + final var image = new Image(IconUtil.class.getResource(path).toExternalForm()); + cache.put(path, image); + return image; + } + } /** * Loads an image from the resource folder and scales it to the given size. @@ -39,9 +49,21 @@ public final class IconUtil { * @param size the size to scale the icon to * @return the scaled image * @since Envoy Client v0.1-beta + * @apiNote There is an extraordinarily low chance that there is a size and name + * conflict. To achieve that however, you basically have to name your + * image intentionally like that. For normal human readable names or + * even automatically generated ones it will never occur. */ public static Image load(String path, int size) { - return new Image(IconUtil.class.getResource(path).toExternalForm(), size, size, true, true); + + // Minimizing the risk of size and name conflict + final var sizeSpecificString = path + size + "+a* "; + if (cache.containsKey(sizeSpecificString)) return cache.get(sizeSpecificString); + else { + final var image = new Image(IconUtil.class.getResource(path).toExternalForm(), size, size, true, true); + cache.put(sizeSpecificString, image); + return image; + } } /** @@ -138,13 +160,19 @@ public final class IconUtil { * @since Envoy Client v0.2-beta */ public static BufferedImage loadAWTCompatible(String path) { - BufferedImage image = null; - try { - image = ImageIO.read(IconUtil.class.getResource(path)); - } catch (final IOException e) { - EnvoyLog.getLogger(IconUtil.class).log(Level.WARNING, String.format("Could not load image at path %s: ", path), e); + if (awtCache.containsKey(path)) return awtCache.get(path); + else { + BufferedImage image = null; + try { + image = ImageIO.read(IconUtil.class.getResource(path)); + } catch (final IOException e) { + EnvoyLog.getLogger(IconUtil.class).log(Level.WARNING, String.format("Could not load image at path %s: ", path), e); + } + + // If an IOException occurs we don't assume it'll be fixed on the next call + awtCache.put(path, image); + return image; } - return image; } /** diff --git a/client/src/main/resources/fxml/ChatScene.fxml b/client/src/main/resources/fxml/ChatScene.fxml index ec6db63..d3fb6e9 100644 --- a/client/src/main/resources/fxml/ChatScene.fxml +++ b/client/src/main/resources/fxml/ChatScene.fxml @@ -175,7 +175,7 @@ - +