Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
student:java:resources [2019/01/24 11:41] – created bernstdhstudent:java:resources [2023/03/30 19:01] (current) bernstdh
Line 10: Line 10:
 ==== Icons ==== ==== Icons ====
  
-To easiest way to refer to icons in a protable fashion is to use a ''%%URL%%'' object (from the ''%%java.net%%'' package), and the easiest way to get the appropriate ''%%URL%%'' object is to use a  ''%%Class%%'' object. For example, if you want to get the  ''%%URL%%'' for a resource named ''%%logo.png%%'' that is  in the ''%%icons%%'' directory **under the top-level directory containing the class of the object referred to by ''%%this%%''** then  you would do the following:+To easiest way to refer to icons in a portable fashion is to use a ''%%URL%%'' object (from the ''%%java.net%%'' package), and the easiest way to get the appropriate ''%%URL%%'' object is to use a  ''%%Class%%'' object. For example, if you want to get the  ''%%URL%%'' for a resource named ''%%logo.png%%'' that is  in the ''%%icons%%'' directory **under the top-level directory containing the class of the object referred to by ''%%this%%''** then  you would do the following:
  
 <code java> <code java>
Line 24: Line 24:
  
 ==== Resource Bundles ==== ==== Resource Bundles ====
 +
 +The static ''%%getBundle()%%'' method in the ''%%ResourceBundle%%'' class can be passed a ''%%ClassLoader%%'' that it will use to locate the resources.  For example, if you want to get the  ''%%ResourceBundle%%'' with the prefix ''%%Strings%%'' that is  in the **top-level directory containing the class of the object referred to by ''%%this%%''** then  you would do the following:
  
 <code java> <code java>
Line 48: Line 50:
 String   line = in.readLine(); String   line = in.readLine();
 </code> </code>
 +
 +
 +==== Copying Resources to a Temporary Directory ====
 +
 +Sometimes it is necessary to copy resources from a %%.jar%% file to a temporary directory on the files system (e.g., if you want to load %%.html%% files that are in a %%.jar%% file into a browser). The following utility class can be used for this purpose.
 +
 +<code java>
 +import java.io.IOException;
 +import java.net.URI;
 +import java.net.URISyntaxException;
 +import java.nio.file.Files;
 +import java.nio.file.FileSystem;
 +import java.nio.file.FileSystems;
 +import java.nio.file.Path;
 +import java.nio.file.Paths;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.stream.Stream;
 +
 +public class ResourceCopier {
 +
 +    /**
 +     * Copy all of the files from a resources package to a temporary directory
 +     * on the file system (whether or not the code and resources are in a .jar
 +     * file or on the file system).
 +     
 +     * This implementation assumes the resource package is a subpackage of the
 +     * package that contains this class (though that can be changed_.
 +     
 +     * @param id The ID to use for the temporary directory
 +     * @param subdir The name of the subpackage that contains the resources
 +     * @return The Path of the temporary directory
 +     * @throws IOException If something goes wrong
 +     * @throws URISyntaxException If something goes wrong
 +     */
 +    public static Path copyResourcesToTemp(String id, String subdir)
 +            throws IOException, URISyntaxException {
 +
 +        // Get the location of the ResourceCopier.class file
 +        String canonicalName = ResourceCopier.class.getName();
 +        String packageName = ResourceCopier.class.getPackageName();
 +        String className = canonicalName.substring(packageName.length()+1) + ".class";
 +        String thisLocation = ResourceCopier.class.getResource(className).toString();
 +
 +        // Remove the file name from the location and create a URI
 +        int fileStart = thisLocation.indexOf(className);
 +        String rootURL = thisLocation.substring(0, fileStart);
 +        URI sourceURI = new URI(rootURL + subdir);
 +
 +        // Get the Path for source files (whether in a .jar file or the file system)
 +        Path sourcePath;
 +        FileSystem fileSystem = null;
 +        if (sourceURI.getScheme().equals("jar")) {
 +            fileSystem = FileSystems.newFileSystem(sourceURI, new HashMap<String, Object>());
 +            sourcePath = fileSystem.getPath("/" + packageName + "/" + subdir);
 +        } else {
 +            sourcePath = Paths.get(sourceURI);
 +        }
 +
 +        // Get a List of all of the files in the source Path
 +        Stream<Path> files = Files.list(sourcePath);
 +        List<Path> filesList = files.toList();
 +
 +        // Create a temporary directory on the local file system
 +        Path temp = Files.createTempDirectory(id);
 +        Path destinationPath = Path.of(temp.toString());
 +
 +        // Copy all of the files from the source Path to the temporary directory
 +        for (Path file : filesList) {
 +            Path targetFile = Path.of(destinationPath.toString(), file.getFileName().toString());
 +            Files.copy(file, targetFile);
 +        }
 +
 +        files.close();
 +        if (fileSystem != null) fileSystem.close();
 +
 +        return destinationPath;
 +    }
 +}
 +</code>
 +
  
  
 ==== Under the Hood ==== ==== Under the Hood ====
  
-These technique uses the ''%%ClassLoader%%'' infrastructure to  retrieve resources from the ''%%.jar%%'' file. So, it is very  important that you understand the relative locations of the  resource and the object that you call ''%%getClass()%%'' on.  A leading ''%%/%%'' will start at the root of the directory  tree,  but you still must understand where in the ''%%.jar%%''  file is the root. Omitting the leading ''%%/%%'', on the other hand, will start at the location of the ''%%.class%%'' file of the object referred to by ''%%this%%''.+These technique use the ''%%ClassLoader%%'' infrastructure to  retrieve resources from the ''%%.jar%%'' file. So, it is very  important that you understand the relative locations of the  resource and the object that you call ''%%getClass()%%'' on.  A leading ''%%/%%'' will start at the root of the directory  tree,  but you still must understand where in the ''%%.jar%%''  file is the root. Omitting the leading ''%%/%%'', on the other hand, will start at the location of the ''%%.class%%'' file of the object referred to by ''%%this%%''.