Making new font available to the JVM - java

I have a Scala/Java service running on a JVM. This is a graphical application that renders images.
While it's running, I want to add fonts it can use. So I install the fonts, and all things work great. EXCEPT that I must restart the service in order for the fonts to work.
So, how to make the JVM load the new fonts I've installed without restarting it?

I can only guess at what you need and give basic examples, before we can help much more you will need to give us more details or an example of how you are currently trying to install/load the font, and how you apply it to your rendered images.
Are you installing the font every time your application runs? This should not be the case, you can do everything from within Java.
Java loads most fonts by itself, so if you are using an already installed/existing font then you can load and use it the normal way, like this:
Font font = new Font("Dialog", Font.PLAIN, 12);
your2Dgraphics.setFont(font);
your2Dgraphics.drawString(String str, int x, int y)
If you want to load the fonts manually from within your program or another directory then you should be doing it like this:
GraphicsEnvironment graphicsEnviro = GraphicsEnvironment.getLocalGraphicsEnvironment();
graphicsEnviro.registerFont(Font.TRUETYPE_FONT, new File("myFontToLoad.ttf"));
Once when you start the program load the font into memory, so you do not have to load it from file every time you need to use it.
I recommend a quick read about fonts in Java, take a look here:
https://docs.oracle.com/javase/tutorial/2d/text/fonts.html

Related

How to change font size on a desktop Java application?

I wrote a program, exported it as ".jar" and ran it on a computer other than my developer desktop PC. The problem arose that the entire JFrame on the laptop was smaller and therefore certain texts were replaced with "..." because the component was too small to display it completely. Now the question arises is there the possibility to change my text size dynamically that it is always getting displayed completely?
Edit 1:
My problem is that I first have to get the font size at which my text is replaced by "...".
|that is the code|
|that is how the gui should look (It looks like this on my desktop pc)|
|that is how the gui looks on my laptop|
I have not really a solution to the problem but I know what was the fault. My windows was scaled to 125% so some text dissapeared...

JavaFx application font on different os

I've finished my JavaFx application and compiled the program. However, my application uses a font from "Apple". When I opened the application on a different OS like my Windows 10 PC, the font was completely different and the things such as buttons and text labels were too long that is created ellipsis ("..."). Is there a way I can transfer fonts over, or force the application to only run under a certain font?
Thanks in advance.
How about setting your controls (buttons,labels etc) to use a safe font family (as described by ampsoft.net and referenced in this question) in your CSS file?
For example:
.button{
-fx-font-family:'serif';
}
.label{
-fx-font-family:'serif';
}

What is the benefit of setting java.awt.headless=true?

I have gone through
Setting java.awt.headless=true programmatically
http://www.oracle.com/technetwork/articles/javase/headless-136834.html
and
Some other links too.
Nowhere it is explained the benefit of using this flag.
Is it a performance benefit? If yes, is there even a rough quntization how much performance benefit there will be? (I know that answers to performance questions totally depend upon case to case, but it would be nice to know if someone reported a good benefit from doing this).
There is no performance benefit of setting java.awt.headless=true if you're not using AWT features. AWT features are loaded on-demand.
As explained in the linked article, headless mode is useful for accessing some Java graphics features which are normally delegated to the graphics host:
After setting up headless mode and creating an instance of the headless toolkit, your application can perform the following operations:
Create lightweight components such as Canvas, Panel, and Swing
components, except the top levels
Obtain information about available fonts, font metrics, and font settings
Set color for rendering text and graphics
Create and obtain images and prepare images for rendering
Print using java.awt.PrintJob, java.awt.print.*, and javax.print.* classes
Emit an audio beep
For example, in headless mode you can create and write image files:
BufferedImage img = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.drawLine(80, 30, 120, 70);
g.drawLine(80, 70, 120, 30);
ImageIO.write(img, "png", new File("image.png"));
When run with -Djava.awt.headless=true, will produce an image file:
When run with -Djava.awt.headless=false (and without an X window server) will throw an exception instead:
java.awt.AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
Note that the JVM contains heuristics that determine the value of java.awt.headless if it's not explicitly set. For example, on Linux if the DISPLAY environment variable is not set, java.awt.headless automatically becomes true.
Headless and non-headless modes are different, they have different set of features. If you only need to do some simple things like font rendering then yes, you will be able to do it in headless mode.
You can always check the guts of the JDK sources and see for yourself, what methods are dependent on non-headless mode. But in my opinion, even if the performance gain is negligible, it's best to pass java.awt.headless anyway (if you do not need "full" GUI mode).
Any vendor can use this property. You never know if they are going to do something if you have the full GUI. So, my rule of thumb is: always use java.awt.headless for the console apps and the servers. It won't harm.
One possible benefit is that if you are invoking the application while trying to do something else in a window perhaps invoking the application multiple times, it will not disrupt your keyboard/mouse focus if the application runs in headless mode.
At least on a Mac I have had huge problems running a script which repeatedly runs a java app every few seconds while trying to edit in another window. Headless mode fixes that.
Headless mode is mainly useful in those systems that don't have a graphical display, typically the servers.
Many applications use graphical displays to do things that are not necessarily needed to be seen, for instance drawing an image and then saving it to disk.
if you run such a program on a server (ssh connections only, no graphic endpoint), you get an exception when in default mode, while you get the program ran when you enable the headless mode.
Headless mode essentially means virtual display, the graphical components do their operations on a generic/transparent display interface, eg, they draw a circle on a grid, then the result is either actually displayed, when in headed mode, or it is treated differently in headless mode, eg, the grid is a memory object, which is changed so that it would represent the drawn circle on a real display, the same grid can be used for tasks like saving everything as an image file.
As suggested by one of the comments, Oracle has a number of details about it.

Font glyph fallthrough in Java

Does anyone know of an existing solution for font glyph fallthrough in Java? For example, our designers have decided that Calibri is the font that mostly fits our needs, but if I specify Calibri, it can naturally not render characters that do not have a matching glyph in that font. In that case, I would need it to fall through to a second specified font, and if all else fails - use one of Java's logical fonts.
Has anyone come up with a solution for this, which can be plugged into existing Swing components without having to write custom Swing components for the entire project?
This is a very old project already, and building custom graphical components is not a feasible solution.
This isn't a code-based solution and probably won't be of much help, since it requires each user to install a file locally, but just in case...
You can add fallback fonts in a special directory within the JRE installation. From the Java documentation:
Users can add a physical font as a fallback font to logical fonts used in Java 2D rendering by installing it in the lib/fonts/fallback directory within the JRE.

Can I set the DPI resolution of my Java Swing application without changing the systems' DPI setting?

I have a Java application using the Substance LookAndFeel with Windows as the the target platform and I want to increase the DPI setting of my application without changing the system setting.
I want to do this because I don't want to force the user to restart Windows and because many Windows applications seem to have problems with very high DPI settings (> 120)
PS: I'm aware that the Substance LaF allows to scale the font size at runtime, but that way only the height of my controls are scaled, not the width. I want my GUI fully scaled as it would happen if I set the system's DPI setting.
Don't know if that is possible. The look&feel would have to support it, and as far as I know, the Windows Look&Feel does not. Here's a hack which you may consider: Iterate through all the fonts defined in your look&feel and redefine them to be slighly bigger. Here is a code snippet that does this:
for (Iterator i = UIManager.getLookAndFeelDefaults().keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
if(key.endsWith(".font")) {
Font font = UIManager.getFont(key);
Font biggerFont = font.deriveFont(2.0f*font.getSize2D());
// change ui default to bigger font
UIManager.put(key,biggerFont);
}
}
I suppose you could take this one step further and redefine scale borders proportionally as well, but that gets very complicated very quickly
So the actual answer seems to be: no you can't. That really is a bummer because it's a pain to test.
Yes you can, but you need to run it on JRE 9.
This is because the Java runtime declared itself to be "DPI-aware" but didn't really supported it for AWT and Swing. Java applications were sized and rendered based on pixels rather than being properly scaled, this included HiDPI displays.
Anyways, this has been recently solved.
See the issue JEP 263: HiDPI Graphics on Windows and Linux
and the upgrade.
So, increasing the font size does not work (because it does not increase the rest of the things); the jvm argument -Dsun.java2d.dpiaware=false does not work (because it was not really supported); and the manifest file + registry edit (for Windows) just does not work.
Solution: You need to run it on JRE 9 because it really supports this feature.

Categories