Closed armin-reichert closed 1 year ago
how would you write such a ResourceLoader class
With a text editor ;-)
No, it is really simple, something like this:
public class ResourceLoader {
/* The path under your src/main/resources folder where you store your images... */
private static final String ROOT = "/";
/**
* @param relativePath relative path (without leading slash) starting from resource root directory
* @return full path to resource including path to resource root directory
*/
private static String toFullPath(String relativePath) {
return ROOT + relativePath;
}
/**
* @param relPath relative path (without leading slash) starting from resource root directory
* @return URL of resource addressed by this path. Never returns <code>null</code>!
*/
public static URL urlFromRelPath(String relPath) {
return url(toFullPath(relPath));
}
/**
* @param fullPath full path to resource including path to resource root directory
* @return URL of resource addressed by this path. Never returns <code>null</code>!
*/
public static URL url(String fullPath) {
Objects.requireNonNull(fullPath);
var url = ResourceLoader.class.getResource(fullPath);
if (url == null) {
throw new MissingResourceException("Missing resource, path=" + fullPath, "", fullPath);
}
return url;
}
/**
* @param relPath relative path (without leading slash) starting from resource root directory
* @return image loaded from resource addressed by this path.
*/
public static Image image(String relPath) {
var url = urlFromRelPath(relPath);
return new Image(url.toExternalForm());
}
}
Why would I use a ResourceLoader instead of what I´ve been doing?
Wenn deine Anwendung später mal in ein jar-File oder ähnlichem gepackt ist, dann lädt man Ressourcen wie Bilder, Fonts, Sounds etc. nicht mehr vom Filesystem sondern mittels Class.getResource oder Class.getResourceAsStream. Und wenn man alle Methoden, um solche Ressourcen zu laden, in einer Klasse sammelt, dann hat man halt sowas wie oben beschrieben.
ok aber wenn ich wie bisher meine Texturen auch skalieren will geht das mit
water = new Image(new File("main/resources/terrain/floor/Water.png").toString(), terrainSize, terrainSize, false, false);
nicht mehr da ich dann new File nicht benutzen kann. Hast du da eine Idee?
Nein, da verstehst Du was falsch.
Das Image erwartet als ersten Parameter ja einen URL (Uniform Resource Locator) und den bekommt Du ja gerade per Class.getResource()
.
Du verwendest also nicht new Image(new File("path").toString(), ...)
sondern
var url = getClass().getResource("/pfad/zum/bild/bildname.png"); // Pfad unterhalb von src/main/resources
var image = new Image(url.toString(), ...);
Das funktioniert sowohl, wenn das Bild vom Fileystem geladen wird, als auch, wenn das Bild mit den Klassen in einem jar-File liegt.
Ich muss allerdings bei
var image = new Image()
einen new File erstellen weil ich ansonsten die geladene Textur nicht skalieren kann und dieser benötigt eine URI oder einen pathname. Irgendwelche Ideen das zu beheben (also die Textur anders zu skalieren oder den ResourceLoader URIs "generieren" zu lassen).
Das ist mein Fehler
for (int i = 0; i < 4; i++) { URL url = getClass().getResource("/player/MovingRight_" + i + ".png"); movingImagesR[i] = new Image(new File(), playerSize, playerSize, false, false); }
Candidates for new File() are:
File(String pathname, int prefixLength)
File(String child, File parent)
File(String pathname)
File(String parent, String child)
File(File parent, String child)
File(URI uri)
Vergiss einfach File(). Das Image erwartet als ersten Parameter ja kein File oder einen Filenamen, sondern einen URL. Und den liefert doch gerade getClass().getResource()
.
aber wie skaliere ich im folgenden mein Image?
Na genau wie vorher, nur dass der erste Parameter von new Image()
nicht new File(...).toString()
sondern getClass().getResource(...).toString()
ist.
Ich hatte wohl einen knick in der Optik. Jetzt habe ich gesehen wie du meinst. Vielen Dank
Prima. Freut mich.
Resources should be loaded via URLs or streams that you create with
Class.getResource()
orClass.getResouceAsStream()
. As I already explained in Reddit, consider providing a Utility class e.g.ResourceLoader
that creates URLs from paths relative to your resource root folder (src/main/resources if following Maven conventions) and that provides methods for loading images, fonts, audio clips etc. accordingly. Then in your code your just can write something like