package com.wilutions.fx.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.scene.image.Image;
public class ResourceLoader {
private static Logger log = Logger.getLogger("ResourceLoader");
private Map<String, Image> images = new HashMap<>();
public ResourceLoader() {
}
public InputStream getResourceAsStream(Class<?> clazz, String resId) {
InputStream ret = null;
try {
ret = clazz.getResourceAsStream(resId);
}
catch (Exception e) {
log.log(Level.WARNING, "Failed to load resource from class=" + clazz + ", resId=" + resId, e);
}
if (ret == null) {
log.log(Level.WARNING, "Missing resource from class=" + clazz + ", resId=" + resId);
ret = new ByteArrayInputStream(new byte[0]);
}
return ret;
}
/**
* Get an image from the resources.
* This function can only be called in the JavaFX UI thread.
* @param clazz Class object used to load the resource.
* @param resId Resource ID.
* @return Image
*/
public Image getImage(Class<?> clazz, String resId) {
// Allow access to UI thread only. This allows to access the map un-synchronized.
if (!Platform.isFxApplicationThread()) {
throw new IllegalStateException("Wrong thread.");
}
Image ret = images.get(resId);
if (ret == null) {
ret = new Image(getResourceAsStream(clazz, resId));
images.put(resId, ret);
}
return ret;
}
/**
* Copy resource into temporary file.
* @param clazz
* @param resId
* @return
*/
public File getFile(Class<?> clazz, String resId) {
int p = resId.lastIndexOf('.');
String fname = p != -1 ? resId.substring(0, p) : resId;
String ext = p != -1 ? resId.substring(p) : ".tmp";
File file = null;
try {
file = File.createTempFile(fname, ext);
try (InputStream istream = getResourceAsStream(clazz, resId);
OutputStream ostream = new FileOutputStream(file)) {
byte[] buf = new byte[10*1000];
int len = -1;
while ((len = istream.read(buf)) != -1) {
ostream.write(buf, 0, len);
}
}
file.deleteOnExit();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
return file;
}
}