8

What I am attempting to do is store a text file (that won't change) inside the JAR of the program so that it can be read. The purpose of the text file is that it will be read in by one of my classes and the contents of the text file will be added to an JEditorPane. The file will basically be a tutorial and when the user clicks on the option to read the tutorial, the file contents will be read and displayed in a new window that pops up.

I have the GUI portion of it down, but as far as storing the file in the JAR so it can be accessed, I am at a lost. I've read that using an InputStream will work, but after trying a few things I haven't gotten it to work yet.

I also store images in the JAR to be used as icons for the GUI windows. This is accomplished with:

private Image icon = new ImageIcon(getClass()
    .getResource("resources/cricket.jpg")).getImage();

But, this doesn't work when trying to get a file:

private File file = new File(getClass.getResource("resources/howto.txt"));

Here is my Class as it is now:

public class HowToScreen extends JFrame{

/**
 * 
 */
private static final long serialVersionUID = -3760362453964229085L;
private JEditorPane howtoScreen = new JEditorPane("text/html", "");
private Image icon = new ImageIcon(getClass().getResource("resources/cricket.jpg")).getImage();
private BufferedReader txtReader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/resources/howto.txt")));

public HowToScreen(){
    setSize(400,300);
    setLocation(500,200);
    setTitle("Daily Text Tutorial");
    setIconImage(icon);

    howtoScreen.setEditable(false);
    howtoScreen.setText(importFileStream());
    add(howtoScreen);
    setVisible(true);
}

public String importFile(){
    String text = "";
    File file = new File("howto.txt");
    Scanner in = null;

    try {
        in = new Scanner(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    while(in.hasNext()){
        text += in.nextLine();
    }

    in.close();
    return text;
}

public String importFileStream(){
    String text = "";
    Scanner in = new Scanner(txtReader);

    while(in.hasNext()){
        text += in.nextLine();
    }

    in.close();
    return text;
}
}

Ignore the importFile method as that is being removed in favor of storing the tutorial file inside the JAR, making the program wholly self contained as I am limited to how much space the program can use.

EDIT: After trying all of the suggestions below, I checked to see if my JAR is packaging the text file in it and it is not. When opening the JAR with 7zip, in my resources folder the picture I use for icons is there, but not the text file.

user2434692
  • 123
  • 1
  • 2
  • 9
  • Describe what "doesn't work" means. If you get an error, show us the error. – Daniel Kaplan Jun 06 '13 at 04:55
  • See also http://stackoverflow.com/q/10452825/180100 –  Jun 06 '13 at 04:58
  • *"I checked to see if my JAR is packaging the text file"* Smart move. :) – Andrew Thompson Jun 06 '13 at 05:36
  • Yea not entirely sure why it isn't included when the I use Eclipse to export a Runnable JAR. – user2434692 Jun 06 '13 at 05:39
  • *"the picture I use for icons is there, but not the text file."* That must be resolved **first** before any of the answers could work. Just in case there is any confusion in that respect. You might 1) Significantly edit this question.. or 2) start a new question, in relation to the missing resource in the Eclipse build. – Andrew Thompson Jun 06 '13 at 10:32

4 Answers4

12

You cannot use File inside a JAR file. You need to use InputStream to read the text data.

BufferedReader txtReader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/resources/mytextfile.txt")));

// ... Use the buffered reader to read the text file.
Sri Harsha Chilakapati
  • 10,962
  • 6
  • 46
  • 87
2

Try the next (with the full path package):

InputStream inputStream = ClassLoader.getSystemClassLoader().
        getSystemResourceAsStream("com/company/resources/howto.txt");
InputStreamReader streamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader in = new BufferedReader(streamReader);

for (String line; (line = in.readLine()) != null;) {
    // do something with the line
}
Paul Vargas
  • 38,878
  • 15
  • 91
  • 139
1

You code will not compile. Class.getResource() returns a URL, and File has no constructor with a URL as an argument.

You can just use .getResourceAsStream() instead, it returns an InputStream directly, you just have to read the contents of the file from that stream.

Note: both of these methods return null if the resource is not found: don't forget to check for that...

fge
  • 110,072
  • 26
  • 223
  • 312
1

the contents of the text file will be added to an JEditorPane.

See DocumentVewer & especially JEditorPane.setPage(URL).

Since the help is an it will be necessary to gain an URL using getResource(String) as detailed in the info. page.

.. tried this: URL url = this.getClass().getResource("resources/howto.txt");

Change:

URL url = this.getClass().getResource("resources/howto.txt");

To:

URL url = this.getClass().getResource("/resources/howto.txt");  // note leading '/'
Community
  • 1
  • 1
Andrew Thompson
  • 163,965
  • 36
  • 203
  • 405
  • I read those and tried this: URL url = this.getClas.getResource("resources/howto.txt"); howtoScreen.setPage(url); With that bit of code, I get a bad url exception, so somehow my program can't find the file? – user2434692 Jun 06 '13 at 05:43
  • Unfortunately that did not work. – user2434692 Jun 06 '13 at 06:06
  • So the `howto.txt` is that and not `HowTo.txt` (case is important)? The resource is in path of the Jar `resources/howto.txt`? Provide the output of `jar -tvf the.jar` – Andrew Thompson Jun 06 '13 at 06:13
  • yes, the text is "howto.txt", no uppercase letters. And I am not sure what you want from "jar -tvg the.jar". I'm guessing that is a command line of some sort? – user2434692 Jun 06 '13 at 06:29
  • That was `jar -tvf the.jar` for a listing of the content and yes, from the command line. – Andrew Thompson Jun 06 '13 at 06:54