2

我的需求集中在我的数据文件所在的位置。当前应用程序在一个 JAR 中包含所有类和数据文件(使用 Eclipse IDE 构建)。

我注意到人们似乎可以通过多种方式获取这些信息。我需要我的图像文件所在的路径(图形)。我还需要它作为使用工具包调用的 URL。

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

但是我在创建 URL 或其他东西时遇到了麻烦。我尝试了几种不同的方法。此时,我将数据文件保存在文件系统中的类文件旁边。我正在为我所做的工作添加另一个功能 - 在调试中运行时剥离 /bin 目录。

// 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);

后来……我去取图,有些电话打不通,不知道为什么

我试过两件事......

// 1
String s = "file://" + rootDataPath + d.toString() + fileName;   
url = frame.getClass().getResource(s);

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

其中任何一个都有问题。
我有电话从不同的地方获取图像。“框架”是整个执行过程中的父框架,在 BwFrame 类中。

在任何尝试中,我的道路都是这样的......

根数据路径:/C:/Users/Markgm/Documents/DEV/workspace/bwp/

因此,我正在寻找方法来打开工具包的 FileInputStream 或 URL,以获取与类文件所在位置相关的文件(以及调试时的一些技巧)。对于客户端应用程序,这就是它。有一天,我可能想将它作为 Applet 运行,但我不知道图像文件必须在哪里。(50x75 扑克牌和一些按钮图像)感谢任何帮助或建议!

TIA,马克

4

2 回答 2

1
Toolkit tk = frame.getToolkit();

不要Toolkit用于加载图像,因为 Java 1.4。改为使用ImageIO.read(String/File/URL),这是一种阻止方法,可确保在返回之前加载整个图像。

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

还有一个实际问题。一旦你有一个URL(或File)对象,不要把它扔掉并使用String表示。更重要的是,不要提供String应该代表 a 的 a File,而是实际上代表 a URL

我没有阅读其余的代码片段(在问题或后续“答案”中),您将来可能希望发布SSCCE

于 2011-08-20T16:31:32.120 回答
0

我完全摆脱了使用 URL,这是从使用粘贴代码开始的。从类文件运行与从 JAR 文件运行时,URL 的行为发生了变化,一切都发生了变化。所以我在这里的代码显示了我最终做了什么,并对发生的事情进行了评论(类文件或 jar 文件),并且我还调整了调试时间以使其工作(从最后剪掉 bin/)。

        // 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);

上图:从 init() 时间开始。下面是一个 getImage() 函数,包括额外的调试相关行。注意: url.getFile() 不能直接工作有两个原因 - 一个是它有文件:/ 当它从一个 jar 中出来时,另一个是因为它不会在其预先声明的根 / 下采用完整的路径规范。

    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;
}
于 2011-08-20T15:46:01.073 回答