In a folder called data, I have a font file called font.ttf.
I want to read it in, like this:
try {
Font f = Font.createFont(Font.TRUETYPE_FONT,
new File("data/font.ttf")).deriveFont(12.0);
} catch (IOException | FontFormatException e) {}
That worked fine up until I removed the same font from the system (it's still in the data folder!).
Now, it's just showing Java's generic font.
Is it even possible to read in a font from a file which is not in the System Fonts folder?
You don't seem to be doing anything with that Font f once you've loaded it in, so you might simply be losing it due to block scoping.
Font fallback = load some system default;
Font myfont = null;
...
try {
File ffile = new File("data/font.ttf");
myfont = Font.createFont(Font.TRUETYPE_FONT, ffile).deriveFont(12);
} catch (FontFormatException ffe) {
System.out.println("Tried to load a bad font...");
ffe.printStackTrace();
} catch (IOException ioe) {
System.out.println("I have no idea what went wrong");
ioe.printStackTrace();
} finally {
loadMyApplication(myfont == null ? fallback : myfont);
}
Or if you absolutely need that font for correct UI building or content rendering, call loadMyApplication in the try block, so that any catches prevent your application from loading.
Related
Launching the jar, the console says that the file is not found and the font is not loaded.
How could I solve this problem?
I got this code:
public class FontLoader {
public static Font load(){
String fontFilePath = Paths.get(System.getProperty("user.dir"), "prova.jar", "Retro Gaming.ttf").toString();
int fontStyle = Font.BOLD;
int fontSize = CenterOnDefaultScreen.center().height*2/100;
Font font = null;
int fontTypeResource = Font.TRUETYPE_FONT;
if((fontFilePath == null || fontFilePath.isEmpty()) || fontSize < 1) {
throw new IllegalArgumentException("load() Method Error! Arguments " +
"passed to this method must contain a file path or a numerical " +
"value other than 0!" + System.lineSeparator());
}
try {
font = Font.createFont(fontTypeResource, new FileInputStream(
new File(fontFilePath))).deriveFont(fontStyle, fontSize);
}
catch (FileNotFoundException ex) {
System.out.println("FileNotFoundException: " + fontFilePath);
}
catch (FontFormatException | IOException ex) {
System.out.println("Exception thrown");
}
return font;
}
}
String fontFilePath = Paths.get(System.getProperty("user.dir"), "prova.jar", "Retro Gaming.ttf").toString();
That.. rather obviously won't work.
You need to use the gRAS (getResourceAsStream) system. File in java (as in, what new FileInputStream needs, the java.io.File object) are actual files. entries inside jar files don't count. It is not possible to refer to that ttf file with a File object, nor to open it with FileInputStream.
Fortunately, the createFont method doesn't demand that you pass a FileInputStream; any old InputStream will do.
The ttf file needs to be in the same classpath root as the this very class you are writing (for example, the same jar). Once you've ensured that is the case, you can use gRAS:
try (var fontIn = FontLoader.class.getResourceAsStream("/Retro Gaming.ttf")) {
Font.createFont(Font.TRUETYPE_FONT, fontIn).deriveFont(.., ...);
}
gRAS looks in the same place as where FontLoader.class lives. From your snippet it sounds like you put the ttf in the 'root' of the jar and not next to FontLoader. The leading slash in the string argument to getResourceAsStream means: Look relative to the root of the place FontLoader is in (so, your jar, presumably).
My goal is to be able to use awesome fonts an a Java GUI. For that matter I searched and found this question.
I chose the second answer to import fontawesome-webfont.ttf with an InputStream. I tailored the code to my needs because I do not need a method for my purpose.
But when it comes to testing it, I get the error: "Problem reading font data" in the line:
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
This is the problematic code:
try (InputStream is = this.getClass().getResourceAsStream("C:/Users/Prak01/Documents/EclipseWorkspace/Zeiterfassung/fontawesome-webfont.ttf")) {
try {
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
font = font.deriveFont(Font.PLAIN, 24f);
TextfieldFont = new JTextField("");
TextfieldFont.setFont(font);
} catch (FontFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
I believe that I did everything according to the rules. The data path is correct. Could it be possible that it is because of the...
this.getClass().getResourcesAsStream();
because I changed it from:
TestFontAwsome.class.getResourceAsStream();
but I believe that it should work with this.getClass() as well.
You have mistakenly assumed that the argument to getResourceAsStream is supposed to be a file name. It is not a file name; it’s a relative URL which is resolved against each entry in the classpath. Generally, this means it should be a path in the same .jar file.
If you want to load a Font directly from a File, don’t use getResourceAsStream. Just open it as a file:
try (InputStream is = new BufferedInputStream(
Files.newInputStream(Paths.get("C:/Users/Prak01/Documents/EclipseWorkspace/Zeiterfassung/fontawesome-webfont.ttf")))) {
Note: You don’t need two try blocks. A try-with-resources statement is allowed to have a catch block:
try (InputStream is = new BufferedInputStream(
Files.newInputStream(Paths.get("C:/Users/Prak01/Documents/EclipseWorkspace/Zeiterfassung/fontawesome-webfont.ttf")))) {
// ...
} catch (FontFormatException e1) {
// ...
}
enter
try {
Image in = Toolkit.getDefaultToolkit().createImage("C:\\User\\test\\1.jpg");
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(in)), "YOur Requested Image", JOptionPane.INFORMATION_MESSAGE);
BufferedImage out = new BufferedImage(in.getWidth(null), in.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = out.createGraphics();
g2d.drawImage(in, 0, 0, null);
g2d.dispose();
ImageIO.write(out, "jpg", new File("C:\\User\\test\\Test01.jpg"));
} catch (Exception ex) {
ex.printStackTrace();
}
Here the directory is my problem when I run this program to my lap its says file does not exit I am change directory and run correctly but when ever I change in to pc or lap its ask its directory how to slove it single code to run every pc or lap
Ultimately, like with any platform/install specific work in a platform independent language such as Java, you'll need to do some horrible hacky stuff (see below) if you want to continue down the hard coded, absolute path route.
If you insist on having an absolute path you could specify a config file that is OS/intall specific for each install like others have mentioned.
Really, in a well designed application you wont need to specify absolute addresses to resources (such as images). Any images your application needs would be in your class-path, or referenced from a fixed point (such as user.home) and only relative (./images/Test001.jpg) paths would be required.
The Hacky (not recommended) Stuff
You could build the path from getting a list of roots with File.listRoots(), in Linux/Unix there will be only one (/), in Windows you'll need to decide which drive to use. Then instead of hard coded file seperators (\ on Linux/Unix, / on Windows, etc), get the OS specific File.seperator.
i.e.
String file = File.listRoots()[0] + //First root found
File.seperator + "User" +
File.seperator + "Test" + //This directory is easier to access with System.getProperty("user.home") though
File.seperator + "Test01.jpg
You can either keep the path configurable or add the location to classpath and use Class.getResourceAsStream() to load the file
You can create properties file on your pc and on your lap. Each of them will contain proper value for path to your file. Then in code you can do:
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
prop.load(input);
String path = prop.getProperty("yourpath");
// your code with reading and writing to files here
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I've attempted to create a custom font using the following method, however it throws an exception :
Stream closed
and nothing happens! How can I import a ttf file from my JAR and use it in Java 2D! I'v managed to get it to work with external files, but it just doesn't work with an InputStream!
public Font gameFont(String filename, float fontSize) {
Font myfont = null;
Font myfontReal = null;
try {
InputStream is = new BufferedInputStream(this.getClass().getResourceAsStream("com/or/dungeon/" + filename));
myfont = Font.createFont(Font.TRUETYPE_FONT, is);
myfontReal = myfont.deriveFont(fontSize);
is.close();
} catch (FontFormatException | IOException e) {
System.out.println(e.getMessage());
}
return myfontReal;
}
You are missing a leading slash. Without it, it is searching relative to the class making the call. Try:
this.getClass().getResourceAsStream("/com/or/dungeon/" + filename));
Alternatively, try:
this.getClass().getClassLoader().getResourceAsStream("com/or/dungeon/" + filename));
I'm currently building an android application that displays a set of pdf files in a ListView. Instead of just displaying the filename I want to grab the Title from the metadata of the pdf and display that in the list, if the file doesnt have a Title set then just use the filename. I'm using iText atm, here is what I have:
File[] filteredFiles = root.listFiles(filter);
for (int i=0;i<filteredFiles.length;i++) {
try {
File f = filteredFiles[i];
PdfReader reader = new PdfReader(f.getAbsolutePath());
String title = reader.getInfo().get("Title");
reader.close();
//Do other stuff here...
} catch (Exception e) {
e.printStackTrace();
}
}
This works fine, its gets the data I want, but its slowww. Also, sometimes I get memory crashes if the file is over 2MB. Is there a better way of doing this? Maybe a way of getting the metadata without having to actually open the pdf file?
Any help is much appreciated, Thanks.
You can try fast PDFParse library. It optimized for performance & small memory consumption.
File[] filteredFiles = root.listFiles(filter);
for (int i=0;i<filteredFiles.length;i++) {
try {
File f = filteredFiles[i];
PDFDocument reader = new PDFDocument(f.getAbsolutePath());
String title = reader.getDocumentInfo().getTitle();
reader.close();
//Do other stuff here...
} catch (Exception e) {
e.printStackTrace();
}
}