What would be getDesktopProperty() for Linux? - java

I have to read the high contrast mode of the native os and have to apply the settings on my product. Now for windows I have done some thing like this:
try {
Toolkit toolkit = Toolkit.getDefaultToolkit();
boolean highContrast = (Boolean)toolkit.getDesktopProperty("win.highContrast.on" );
}catch(Exception e) {
}
This works fine for Windows but I need the desktop property to read linux high contrast settings. Can anyone please tell me what would be the desktop property for linux?

I think there is no good method to check high contrast mode in Linux whenever you using Java or not (X11 itself have no high-contrast feature and Linux have a vast variety of UI frameworks and each of them may implement high contrast in it's own way).
Strictly speaking you'll have a bunch of problems with this in Windows too (see here, or here).
There are two possible options to solve the case: just use system colors in your UI using SystemColor class (if that's just what you need) or use the same class for analyzing a contrast between current foreground and background colors (if you need to know if system colors are high contrast). You can also check the system theme name, but it's quite unreliable method.

Related

user's preferred contrast polarity? (OS dark mode setting)

Current operating systems (e.g. Windows, macOS) let the user decide if they want dark content on light blackground (classic) or rather light content on dark blackground (dark mode).
Is there something available in Java, so that my (client side) Java programs can automatically adjust their contrast polarity according to that OS user setting? I am using Swing, if that matters.
I found the system property apple.awt.application.appearance, but nothing for Windows and nothing operating system independent.
And also, is there a listener? Because that setting might change on runtime.
Motivation: inverse contrast polarity seems to inhibit myopia (Aleman et al. 2018-07-18 Science)
There seems to be a way.
First understand that the setting of the desktop mode (light vs dark) can be read from the Windows Registry: How to detect Windows 10 light/dark mode in Win32 application?
Then it is just a question how to obtain access to this registry setting from your java application, which is described here: Read/write to Windows registry using Java
There is a feature request (JDK-8235460) submitted in 2019.
In the meantime you might want to try jSystemThemeDetector (Apache-2 license). This library works on Windows, macOS and some Linux distributions.
OsThemeDetector.getDetector().isDark()
You can also add a listener to detect changes.
OsThemeDetector.getDetector().registerListener(isDark -> {
SwingUtilities.invokeLater(() -> {
if (isDark) {
// The OS switched to a dark theme
} else {
// The OS switched to a light theme
}
});
});
Note: For JavaFX you use Platform.runLater instead of SwingUtilities.invokeLater.

Is there a cross-platform way to set the desktop background in Java? [duplicate]

I have an idea for a class project which involves changing the desktop background image at different times. I saw these questions:
Can I change my Windows desktop wallpaper programmatically in Java/Groovy?
Programmatically change the desktop wallpaper periodically
Change desktop background of MAC sytem using Java native access
So I know it can be done on a specific operating system. Is it possible to set it for different operating systems without writing separate programs?
You can just use:
String os = System.getProperty("os.name");
to determine what OS the app is running on, and decide what to do from there. Like so:
if (os.startsWith("Windows")) {
// includes all Windows versions
} else if (os.startsWith("Mac")) {
// includes all Mac OS versions
} else {
// all others
}
I suggest looking up all of the different values os.name can have to be able to handle as many as possible. You might want to use enums for these values instead of checking startsWith like I did. Here is a list of values you might want to consider (although not very up to date).

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.

Getting the OS Animation preferences in Java

I have a Java app whose windows and internal components have animations that could slow down a less powerful computer. I know that all OSs have some form of animation preferences (In Windows, there are check boxes for "Animate controls and elements inside windows", in Linux, there are selections for Full, Basic, or No animations, and in OSX you can do things like enter "defaults write com.apple.dock workspaces-edge-delay -float 0.0; killall Dock" or "defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO" into the terminal). Is there any way to find out whether the user has animations enabled or disabled, so that I can conform to er preferences?
I would think, that since Java is Operating System agnostic, that there is no specific API, native or third-party, to do this (although there could be). You could use a combination of JNI and/or executing external commands and then interpret their outputs to determine if animations are enabled. To do this you would have to query the os.name system property and run the specific commands for that OS. I think this would be a fair bit of pain and you may just want to give the users an option to disable the animations.
Personally, I would prefer the option because I might turn of the OS animations because they are annoying but still may enjoy the animations in your application.

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