This code works perfectly fine when I run it as a class file (the font is located in the same directory) - however when I package it into a JAR file it can't find the font and the program crashes.

The font is definitely being included in the JAR archive, so I suspect I'm not using the correct syntax to point to it.

How would I modify this so that it works in both cases?

// Text area font
try
{
	// Determine the font file path
	String path = System.getProperty("java.class.path");
	String fileseparator = System.getProperty("file.separator");
	int pathlength = path.length();
	if (path.charAt(pathlength-1) != fileseparator.charAt(0)) { path += fileseparator; }
	path += "Inconsolata.pfa";
	
	// Make the font the proper size
	Font STEFont = Font.createFont(Font.TYPE1_FONT, new File(path));
	STEFont = STEFont.deriveFont(15.0f);
			
	// Add the font to STE
	jTextArea.setFont(STEFont);
			
}
catch (Exception e)
{
	e.printStackTrace();
}

When running the JAR file using Windows Explorer there are no error messages (literally, nothing seems to happen). When I run it from the console this is returned:

java.io.IOException: Can't read STE.jar\Inconsolata.pfa
	at java.awt.Font.createFont(Font.java:978)
	at TextEditorFrame.<init>(TextEditorFrame.java:605)
	at TextEditor.<init>(TextEditor.java:26)
	at TextEditor.main(TextEditor.java:104)
An unexpected problem occurred. Please report this so it can be fixed, including the error message that you see below.

java.lang.NullPointerException

The last part is a custom error message I've put into a catch block in the TextEditor class (the class with the main method).

TextEditorFrame is a class that extends JFrame, and the code I posted above in the first code block is located inside the constructor of this class.

Update: If you want to attempt to reproduce this, you'll probably need the font as well. The font can be downloaded here: http://www.levien.com/type/myfonts/inconsolata.html (use the link titled "pfa file").

Does an overload of createFont() method take a URL instead of a File?
The classpath for code in a jar is the jarfile which is NOT useable in a File constructor.
Add some debugging code to print out the values returned by the various method calls you are using.
To get a file from the jar file, look at using the getResource method.

I've been using the getResource method for gif files just fine, but that didn't seem to work for the font. I think the reason was what you mentioned - that there is no overload of createFont() that takes a URL.

I'll have another look at the getResource method then, perhaps I missed something last time I looked. I'll check again to make sure there's no way for me to pass a URL to createFont().

Okay, the only two versions of the createFont() method are:

  • static Font createFont(int fontFormat, File fontFile)
  • static Font createFont(int fontFormat, InputStream fontStream)

The only versions of the getResource() method are:

  • URL getResource(String name)
  • InputStream getResourceAsStream(String name)

So... if I understand this correctly I can use the second version of each. The getResource one to get an InputStream for the font... and then plug that into the second createFont method?

I'll see if I can get that working now.

Works perfectly! Thanks! :)

Posting a list of parameters and return types helped me to find the answer. It was right in front of me the whole time - I just didn't notice.

Congratulations. There was a connection between the URL and the InputStream needed int the method call.

Thanks so much for this info!
I've been struggling with the same issue, didn't even notice the inputStream possibilities...
you made my day :)

Hope someone could provide me complete code or correct my code...

Here is my code:
static Font teFont = null;
static Font tFont = null;
String url = "build/classes/com/font/myFont.ttf";
InputStream is = this.getClass().getResourceAsStream(url);
teFont = Font.createFont(Font.TRUETYPE_FONT, is);
tFont = Font.createFont(Font.TRUETYPE_FONT, is);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(teFont);
ge.registerFont(tFont);
teFont = teFont.deriveFont(12.0f);
tFont = tFont.deriveFont(10.0f);

Here is compiling code:
Exception in thread "main" java.io.IOException: Problem reading font data.
at java.awt.Font.createFont(Font.java:924)
at com.main.FontTester.<init>(FontTester.java:36)
at com.main.FontTester.main(FontTester.java:161)

Probably need to reset the inputstream

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.