I need to use custom fonts (ttf) in my Java Swing application. How do I add them to my package and use them?
Mean while, I just install them in windows and then I use them, but I don't wish that the usage of the application will be so complicated, it`s not very convenient to tell the user to install fonts before using my application.
You could load them via an InputStream:
InputStream is = MyClass.class.getResourceAsStream("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
This loaded font has no predefined font settings so to use, you would have to do:
Font sizedFont = font.deriveFont(12f);
myLabel.setFont(sizedFont);
See:
Physical and Logical Fonts
As Reimeus said, you can use an InputStream. You can also use a File:
File font_file = new File("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, font_file);
In both cases you would put your font files in either the root directory of your project or some sub-directory. The root directory should probably be the directory your program is run from. For example, if you have a directory structure like:
My_Program
|
|-Fonts
| |-TestFont.ttf
|-bin
|-prog.class
you would run your program with from the My_Program directory with java bin/prog. Then in your code the file path and name to pass to either the InputStream or File would be "Fonts/TestFont.ttf".
Try this:
#Override
public Font getFont() {
try {
InputStream is = GUI.class.getResourceAsStream("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
return font;
} catch (FontFormatException | IOException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
return super.getFont();
}
}
Related
I was trying to read a .ttc file using java.io.InputStream in IntelliJ IDEA, but it failed.
Here is my code:
InputStream inputStream = getClass().getResourceAsStream("Dependencies\\msjh.ttc");
Font font;
try
{
if (inputStream == null)
throw new IOException();
font = Font.createFont(Font.TRUETYPE_FONT, inputStream).deriveFont(Font.PLAIN);
}
catch (IOException | FontFormatException exception)
{
font = new Font("Microsoft JhengHei UI", Font.PLAIN, 16);
}
No matter how I try, the condition if (inputStream == null) is always true and the IOException will be thrown.
But a similar way of setting window icon works:
Frame frame = new Frame("Window");
frame.setIconImage(Toolkit.getDefaultToolkit().getImage("Dependencies\\icon.png"));
Here are paths from my files :
IdeaProjects\Project\Dependencies\msjh.ttc (font file)
IdeaProjects\Project\Dependencies\icon.png (image file)
IdeaProjects\Project\src\bin_gen\Main.java (source code)
and there is a VM option: -Dfile.encoding=MS950
That .ttc file was copied from C:\Windows\Fonts\Microsoft JhengHei UI. I'm trying this because font = new Font("Microsoft JhengHei UI", Font.PLAIN, 16); seems not working (The font display on the window is still the default font).
I recommend to use getResource rather than getResourceAsStream. They follow slightly different rules and I understand the rules of the former well.
If the font is in the Jar created by the IDE, it will be located at /Dependencies/msjh.ttc.
Note the two separate forward slashes (/) as opposed to a file-like back-slash (\\). That backslash is only for files, and only on Windows. What getResource needs is a resource path either direct from the project or jar root, or relative to the class calling it. The / prefix tells the JRE to look for the resource from the root of the classpath, rather than relative to the calling class.
Also don't use getImage("Dependencies\\icon.png"). That will presume the string represents a file path, which won't work when the project is deployed. Use getResource for that as well.
I have a Java project that has a custom font and when compiled on other computers the font is not the same because my font is not compiled with it. How do I compile with it so it works on other PCs?
This code won't work. Entered it in all my WindowOpened.
try {
InputStream istream = getClass().getResourceAsStream("/fonts/cs_regularttf");
Font myFont = Font.createFont(Font.TRUETYPE_FONT, istream);
} catch (FontFormatException fontFormatException) {
} catch (IOException iOException)
{
}
EDIT: Using the stack trace method, this is what I get for me code.
java.io.IOException: Problem reading font data.
at java.awt.Font.createFont0(Font.java:1000)
at java.awt.Font.createFont(Font.java:877)
at projetfinal.frmMenu.<init>(frmMenu.java:56)
at projetfinal.ProjetFinal.main(ProjetFinal.java:20)
If you use getClass().getResourceAsStream(...) this will interpret the given path relative to your current package (and thus you'd have to put your font in /path/to/your/classes/package/fonts within a resources/ directory of your NetBeans project.
Otherwise you may use getClass().getClassLoader().getResourceAsStream() and omit the package part.
I am trying to hack together a game in Java, and on the start screen I used a custom font I downloaded. When I run the program from Eclipse, the screen looks like this (just as it should):
However, when I run the program from the compiled jar, the screen looks like this:
Here is my code for loading the font:
title = new JLabel("philip k. dick"); // font requires all lowercase
try {
Font f = Font.createFont(Font.TRUETYPE_FONT, new File(Util.getFile("all used up.ttf")));
title.setFont(new Font(f.getName(), f.getStyle(), 150));
} catch (Exception e) {
e.printStackTrace();
Font oldFont = title.getFont();
title.setFont(new Font(oldFont.getName(), oldFont.getStyle(), 100));
}
The method Util.getFile just adds "resources/" to the beginning of the given String.
There are no errors given when I run the jar from the command line. I know that the program can access the font resource because when I rename the "resources" folder (to prevent access), the screen looks like this:
Additionally, I get this error:
java.io.IOException: Can't read resources/all used up.ttf
Of course, THIS is expected.
I would also like to note that I have other audio and image resources being loaded from the same location, and they work fine. This location is in the folder directly outside of the jar. Also, I am using a Mac, but I get the same problem on Windows.
The contents of your resources directly are typically add to your Jar.
This means that they can no longer be access using a File object, as they are actually now part of a Zip file.
You need to use something like getClass().getResource(...) to it up. This returns an instance of URL which points to the resource (if it can be found)
However, Font.createFont takes either a File or InputStream reference, in this case you should use getClass().getResourceAsInputStream(...), something like...
Font f = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsInputStream("resources/all used up.ttf"));
This makes a "relative" path request from the context of the class trying to load the resource. This is probably not going to work, so instead, you could use
getClass().getResourceAsInputStream("/resources/all used up.ttf")
Which creates an absolute path lookup from the context of the classpath
If you get stuck, try unpacking the Jar and see if the font resides within and where and make adjusts as required.
Updated...
Try using...
Font f = Font.createFont(Font.TRUETYPE_FONT, new File("resources/all used up.ttf"));
title.setFont(f.deriveFont(150f));
As I understand it, new Font(...) is trying to find the font from the available system fonts.
From the Java Docs for Font#createFont...
This base font can then be used with the deriveFont methods in this
class to derive new Font objects with varying sizes, styles,
transforms and font features. ...To make the Font available to Font
constructors the
returned Font must be registered in the GraphicsEnviroment by calling
registerFont(Font).
I had developed software in eclipse and platform was ubuntu (linux). I used gujarati fonts in program and completed it and it runs wery well in ubuntu but while running in windows 7 with JRE it doesnt work properly. Text won't show properly as it used in ubuntu. What shoud I do?
I have tried using java -Dfileencoding=utf-8 also but it wont worked properly. While I open java sorce file picked from Ubuntu in Windows the text works and shows properly.
So please tell me the way to do work this properly.
If you want to use a custom font in your application (that isn't available on all operating systems), you will need to include the font file (otf, ttf, etc.) in your .jar file, you can then use the font in your application via the method described here:
http://download.oracle.com/javase/6/docs/api/java/awt/Font.html#createFont%28int,%20java.io.File%29
Sample code from (Here thanks to commenter);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf")));
If your unsure on how to extract your file from a .jar, here's a method I've shared on SO before;
/**
* This method is responsible for extracting resource files from within the .jar to the temporary directory.
* #param filePath The filepath relative to the 'Resources/' directory within the .jar from which to extract the file.
* #return A file object to the extracted file
**/
public File extract(String filePath)
{
try
{
File f = File.createTempFile(filePath, null);
FileOutputStream resourceOS = new FileOutputStream(f);
byte[] byteArray = new byte[1024];
int i;
InputStream classIS = getClass().getClassLoader().getResourceAsStream("Resources/"+filePath);
//While the input stream has bytes
while ((i = classIS.read(byteArray)) > 0)
{
//Write the bytes to the output stream
resourceOS.write(byteArray, 0, i);
}
//Close streams to prevent errors
classIS.close();
resourceOS.close();
return f;
}
catch (Exception e)
{
System.out.println("An error has occurred while extracting a resource. This may mean the program is missing functionality, please contact the developer.\nError Description:\n"+e.getMessage());
return null;
}
}
You'll need to install the font into Windows - or change the font on your application. You can do this by including it in your install process.
Is it possible to write a GUI in Java that would display Japanese fonts correctly regardless of the language settings of the OS it's being run on?
I'd like to write a program which is able to do this but I'm not sure how to start going about this. Any advice would be a huge help!
The language settings aren't the problem here. Fonts are.
Java certainly can handle Japanese text, no matter what the system settings are, if the developer doesn't fall into the trap of depending on the platform default encoding by using things like FileReader, or new String(byte[]).
But to actually display the Japanese text, you need a font that has Japanese characters, and fonts are not part of Java. Depending on the OS, Japanese-capable fonts may be part of the default installation, or the user may be prompted to install them as needed, or they may have to be installed manually.
Java can easily display Japanese regardless of if the OS has the fonts installed or not, but this is only for Swing applications. Anything using the console window requires fonts installed in the OS.
Steps:
1) Download one of the truetype fonts from here : http://www.wazu.jp/gallery/Fonts_Japanese2.html
2) Use the following code to allow your swing clients to use your fonts:
InputStream fontStream = getClass().getResourceAsStream("/locationoffontonclasspath/myfontname.ttf");
Font japaneseEnabledFont = null;
boolean japaneseDisplayEnabled = false;
try {
japaneseEnabledFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(japaneseEnabledFont);
japaneseDisplayEnabled = true;
} catch (Exception e) {
// handle exceptions here
} finally {
if (fontStream != null) {
try {fontStream.close();} catch (Exception e1) {}
}
}
if (japaneseDisplayEnabled) {
.....
}
Also, if you wish to use Japanese literals in your sourcecode you have to compile with -Dfile.encoding=utf-8. If using an IDE to compile then you can change the settings on the following screen (right click the project and select properties to get this window): screenshot
More information is available at this page
You can package a TrueType font with your program and load and use it in Swing components like so:
// Create a label in Japanese.
String message = "かつ、尊厳と権利とについて平等である。";
JLabel label = new JLabel(message);
// Load the TrueType font with Japanese characters and apply it.
File file = new File("msmincho.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, file);
font = font.deriveFont(Font.PLAIN, 14f);
label.setFont(font);
Be careful to use the correct charset. If compiling Japanese characters in the code you should compile with javac -encoding utf-8 Foo.java. Also be sure to use the charset explicitly when using Readers.
Add -Dfile.encoding=utf-8 to your command line script that's launching the application.
You can copy your truetype Japanese fonts in $JAVA_HOME\jre\lib\fonts\fallback.
You'll have to create this folder. On linux a symbolic link will do the trick.
Source: http://www.asahi-net.or.jp/~ik2r-myr/kanji/german/linos_g.htm