开发者

My working directory, files, and urls

I have a convergence of needs revolving around where my data files are. The current application has all class and data files in a JAR (building using Eclipse IDE).

I've noticed there seem to be a variety of ways in which people get this information. I need the path for where my image files are (graphics). I also need it as a URL o use the toolkit call.

Toolkit tk = frame.getToolkit();
image = tk.getImage(url.toFile());

But I am having trouble with creating the URL or something. I have tried a few different methods. At this point, I keep data files next to class files in the file system. I am adding another function to what I do - strip the /bin directory off when running in debug.

// in class BwServices at init:
try {
    rootDataPath = BwServices.class.getProtectionDomain()
        .getCodeSource().getLocation().getPath();
    rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
        fileSystemAccess = true;
} 
if(rootDataPath.endsWith("/bin/"))  
    rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);

Later on... I go to get images, and some calls don't work, I don't know why

I've tried two things....

// 1
String s = "file://" + rootDataPath + d.toString() + f开发者_开发技巧ileName;   
url = frame.getClass().getResource(s);

// 2
    try {
        url = new URL(s);
    } catch (MalformedURLException e) {
        trace("getImage - can't get url: " + s);
        e.printStackTrace();
    } 

Either of which has problems.

I have calls to get images from different places. The 'frame' is the parent frame throughout the execution, in class BwFrame.

My path comes out like this in any attempts...

rootDataPath: /C:/Users/Markgm/Documents/DEV/workspace/bwp/

So, I'm looking for ways to open either FileInputStream or URLs for the toolkit, for files relative to where the class file is (and with some trick for when in debug). For a client-side app this is what this is. Someday, I might want to run this as an Applet, but I don't know where the image files will have to be. (50x75 playing cards and a few button images) Any help or advice is appreciated!

TIA, Mark


Toolkit tk = frame.getToolkit();

Don't use Toolkit to load images, since Java 1.4. Use ImageIO.read(String/File/URL) instead, which is a blocking method that ensures the entire image is loaded before returning.

image = tk.getImage(url.toString());

And there is an actual problem. Once you have an URL (or File) object, don't toss it away and use the String representation. Even more importantly, don't provide a String that is supposed to represent a File, but actually represents an URL!

I didn't read the rest of that mess of code snippets (in the question or follow-up 'answer'), you might look to post an SSCCE in future.


I got rid of using URLs at all, which started with the use of pasted code. The behavior of URLs changed, as did everything, when running from a class file versus running from a JAR file. So I have code here that shows some of what I ended up doing, and comments to what happens (class file or jar file), and I also got the adjustment for debug time to work (snipping off bin/ from the end).

        // root path - starts with jar file or pathspec
    try {
        rootDataPath = BwServices.class.getProtectionDomain()
                    .getCodeSource().getLocation().getPath();
        rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
        if(rootDataPath.endsWith("BwPlayer.jar"))
            rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 12);
        fileSystemAccess = true;
    } catch(SecurityException e) {
        trace("No file system access: " + e.getMessage());
        messageBox(frame, "BwServices", "Cannot access file system");
        rootDataPath = "";
    } catch (UnsupportedEncodingException e) {
        trace("Jar URL decode exception: "+ e.getMessage());
    } 
    if(rootDataPath.endsWith("/bin/"))  // remove bin/ portion if in debug
        rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);
    trace("rootDataPath: "+rootDataPath);

Above: from init() time. Below, a getImage() function, including extra debug-related lines. Note: url.getFile() doesn't directly work for 2 reasons - one is it has the file:/ when out of a jar, and the other because it won't take a full pathspec beneath its pre-stated root /.

    static public Image getImage(Directory d, String fileName) {
    Image image = null;
    String s = d.toString() + fileName;
    /*
    // Note: Start with / required for this url call (w/o full pathsepc)
    URL url = parentFrame.getClass().getResource("/" + s);
    if(url == null) {
         trace(s + " - null url ");
         return null;
    }
    */
    String file = rootDataPath + s; // url.getFile();
    // end note
    String t = s = "getImage(" + file + ") ";

    Toolkit tk = parentFrame.getToolkit();
    if(tk == null)
        s = s + "NULL tk ";
    else {
        try {
            // full pathspec needed here 
            // url.getFile() returns with file:/ when running from the .jar file
            //  but not when running from .class file (so don't use it)
            s = t = "getImage(" + file + ") ";
            image = tk.getImage(file); //url.getFile());
            MediaTracker media = new MediaTracker(parentFrame);
            media.addImage(image, 0);
            try {
                media.waitForID(0);
            } catch(InterruptedException e) {
                s = s + e.getMessage();
            }       
            if(image == null) {
                // image = null;
                s = s + "NULL image ";
            } else if(image.getHeight(parentFrame) < 1) {
                s = s + "invalid height";
            }
        } catch (SecurityException e) {
            s = s + e.getMessage();
        }
    } 

    if(! s.equals(t)) {
        s = "file=" + file + "\n" + s;
        s = "rootDataPath=" + rootDataPath + "\n" + s;
        messageBox(parentFrame, "getImage()", s);
    }
    return image;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜