I am going through some tutorials and I have a problem with loading font file into Eclipse Java Project. I tried many solutions suggested here on SO, and eventually find one (using FileInputStream) which does work for me, but not when the project is exported as runnable JAR. On the other hand using same directory structure in the other project where I load icons works, so I guess the problem is not in the path itself.
Here is the directory structure:
Here is the code:
package examples;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Test01 extends JPanel {
String text = "Free the bound periodicals";
Font fon;
FileInputStream fis;
// InputStream fis;
@Override
public void paintComponent(Graphics comp) {
Graphics2D comp2D = (Graphics2D) comp;
// This (for another project) works both in Eclipse and in runnable JAR
// ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));
// This (quite contrary to many SO suggestions) doesn't work in Eclipse for this project, why?
// fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");
// This (quite contrary to many SO suggestions) doesn't work in Eclipse for this project, why?
// fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");
// This works within Eclipse project but not when exported to runnable JAR,
// Moreover many suggest that InputStream should be favored over FileInputStream
try {
fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));
} catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(this, "FileNotFoundException!");
} catch (URISyntaxException e1) {
JOptionPane.showMessageDialog(this, "URISyntaxException!");
} catch (Exception e1) {
JOptionPane.showMessageDialog(this, "NullPointerException!");
}
try {
fon = Font.createFont(Font.TRUETYPE_FONT, fis);
} catch (FontFormatException e) {
// TODO Auto-generated catch block
System.out.println("Error - FontFormatException " + e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Error - IOException " + e.getMessage());
}
fon = fon.deriveFont(Font.PLAIN, 72);
FontMetrics metrics = getFontMetrics(fon);
comp2D.setFont(fon);
comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x = (getSize().width - metrics.stringWidth(text)) / 2;
int y = getSize().height / 2;
comp2D.drawString(text, x, y);
}
public static void main(String[] args) {
JFrame mainFrame = new JFrame("Main Menu");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(1000, 250);
mainFrame.setVisible(true);
mainFrame.add(new Test01());
// mainFrame.pack();
}
}
So, what bothers me is:
- Why this is not working (seems it cant find font file) as it throws NullPointerException
fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");
nor this is working
fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");
- Why this works within Eclipse project, but not when exported to runnable JAR
fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));
UPDATE As it turned out this will work:
fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");
The problem was in first slash - path should be "examples/resources/verdana.ttf" instead of "/examples/resources/verdana.ttf". It works both in Eclipse and in runnable JAR.
Now, what intrigues me is why is then that first slash necessary in this case
ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));
UPDATE 2: After being frustrated why this method doesn't work
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
I deleted whole class from Eclipse and now BOTH methods work within Eclipse and runanble JAR - just as it should be.
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
or
InputStream fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");