Awesome Fonts: "pr0blem reading font data" in Java - java

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) {
// ...
}

Related

PDF Box - Unable to renameTo or Delete files

I'm fairly new to programming and I've been trying to use PDFBox for a personal project that I have. I'm basically trying to verify if the PDF has specific keywords in it, if YES I want to transfer the file to a "approved" folder.
I know the code below is poor written, but I'm not able to transfer nor delete the file correctly:
try (Stream<Path> filePathStream = Files.walk(Paths.get("C://pdfbox_teste"))) {
filePathStream.forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
String arquivo = filePath.toString();
File file = new File(arquivo);
try {
// Loading an existing document
PDDocument document = PDDocument.load(file);
// Instantiate PDFTextStripper class
PDFTextStripper pdfStripper = new PDFTextStripper();
String text = pdfStripper.getText(document);
String[] words = text.split("\\.|,|\\s");
for (String word : words) {
// System.out.println(word);
if (word.equals("Revisão") || word.equals("Desenvolvimento")) {
// System.out.println(word);
if(file.renameTo(new File("C://pdfbox_teste//Aprovados//" + file.getName()))){
document.close();
System.out.println("Arquivo transferido corretamente");
file.delete();
};
}
}
System.out.println("Fim do documento: " + arquivo);
System.out.println("----------------------------");
document.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
I wanted to have the files transferred into the new folder. Instead, sometimes they only get deleted and sometimes nothing happens. I imagine the error is probably on the foreach, but I can't seem to find a way to fix it.
You try to rename the file while it is still open, and only close it afterwards:
// your code, does not work
if(file.renameTo(new File("C://pdfbox_teste//Aprovados//" + file.getName()))){
document.close();
System.out.println("Arquivo transferido corretamente");
file.delete();
};
Try to close the document first, so the file is no longer accessed by your process, and then it should be possible to rename it:
// fixed code:
document.close();
if(file.renameTo(new File("C://pdfbox_teste//Aprovados//" + file.getName()))){
System.out.println("Arquivo transferido corretamente");
};
And as Mahesh K pointed out, you don't have to delete the (original) file after you renamed it. Rename does not make a duplicate where the original file would need to be deleted, it just renames it.
After calling renameTo, you shouldn't be using delete.. as per my understanding renameTo works like move command. Pls see this

Java: Font does not load (from external file)

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.

Importing Fonts from JAR file

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

Android reading pdf metadata - memory issue

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();
}
}

Read / Write XML file from Java application bundle

I've got an XML file that is parsed and written in my application. From within my IDE (Eclipse) I simply address it like this:
Reading:
private String xmlFile = "file.xml";
and then I build the document:
doc = sax.build(xmlFile);
Writing is done like this:
writer = new FileWriter("file.xml");
Runs great so far, but after bundling my application, the file is no longer accessible.
What exactly do I have to do to make it accessible from within an application bundle?
I'm absolutely not familiar with the classpath or whatever I need for that, so please go easy on me!
Thank you very much!
To read the file you can create a BufferedReader as follows:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
getClass().getResourceAsStream("file.xml")));
You can write the file as before, but keep track of where it's written to - then you can re-read the file from there if necessary.
Peter,
I've run into a similar issue, and since you're new to this, I'll start with this: When you package a file in a jar, it is compressed, and so accessing it like you have in your original code will not work, as we cannot read the files compressed in the jar. Instead, you need to ask Java to pull out this resource as a stream (as many others have helpfully pointed out) which Java does know how to supply to you.
Now, actually outputting the file from there IS a pain. Here's some code I wrote a while back to do this, which is of course from some other source I found. Fill in the exceptions as needed! =)
InputStream in = null;
in = this.getClass().getResourceAsStream("/main.cc");
File outputFile = createMainOutputFile();
OutputStream out = null;
try {
out = new FileOutputStream(outputFile);
} catch (FileNotFoundException e) {
System.out.println(outputFile + " was not found!");
e.printStackTrace();
}
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
We actually have to output the file piece by piece, sad I know, I really wish what you were hoping to do worked! It'd make life a lot easier. The only thing that may be confusing there is the createMainOutputFile() call, so here's the code for that too...
private File createMainOutputFile() {
File directoryPath = new File(mainOutputFolder);
directoryPath.mkdirs();
File newFile = new File (mainOutputFolder + "main.cc");
try {
newFile.createNewFile();
} catch (IOException e) {
System.out.println("failed To create new file.");
e.printStackTrace();
}
return newFile;
}
Best of Luck!
Edit: Now that I notice you're actually parsing it with an XML parser, I'll point out to you that if you're using a SAX parser (at least apache's) you'll find that it will actually accept an inputStream just like it would a file:
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = null;
try {
docBuilder = docFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//Here we supply the inputStream instead of the file...
doc = docBuilder.parse(inputStream);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Node xmlRoot = doc.getFirstChild();
Imagine that you have a package named myXmlDir put your file.xml file under this package (a directory actually)
Notice that this package is packaged with you class inside the jar and can be accessed by the classLoader.
See this code that return an input stream:
return SomeClass.class.getClassLoader().getResource("myXmlDir/file.xml").openStream();
you can also, instead of openStream(), activate the getFile() function
I can't comment, so my answer is referring to LES2's answer. The trick is that your file.xml must be on the classpath if you want to use a classloader.
Usually, it will be included in the classpath if it is in your JAR file. to check if it's there, open the jar with 7zip or any other zip program.
If the file is not inside the jar, you must ship it along with the jar and add it to the classpath manually when starting the app.
lets say file.xml and the jar are in the same directory. then
java -cp .:myjar.jar com.example.Main
should help.
Use the file as a property. You can than do with it whatever you want. To access it use
Class.getResourceAsStream()
or an equivalent method. Check out this link for a few hints: http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html?page=2
Edit:
I'm sorry to say that my suggestion isn't as good as I thought it was. I felt that I had done something as you want to once but I looked at the app and all I did was read the files.
I also did a bit of googleing and found this forum entry which is a bit old but considering the lacking progress on Sun's part I reckon it's essence is still valid: http://lists.apple.com/archives/Java-dev/2003/Feb/msg00876.html
Basically, if you want to write something, either require the user to extract the jar before launching or (my suggestion) create a directory in the same directory as the jar is in and write your file to that directory. If you really needed to, you could even build another jar with that file and all the files of the original jar, which would of course leave you with two archives.
Sorry for bringing your hopes up.
Best option to this common problem:
Absolute path for the location outside the jar/war.
The the app itself can be deployed anywhere, but the host should have a common file area such as "/common/files/someApplication"
Better yet is to have a configuration to specify (during build or at runtime) which path to use. E.g. dev build would use "/dev/myprojects/someApplication"
Not as good solution:
Deploy as exploded war file. Read and write is not a problem, but now you've cause a deployment dependency.
your input should be the absolute or relative path of the file....

Categories

Resources