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.
Related
Does X-Windows have to be installed on a Linux-box in order for Java to display fullscreen graphics?
Well "fullscreen graphics" is a bit vague.
Anyway, apparently there is a an effort ongoing to access the framebuffer from Java: Framebuffer Toolkit.
The objective of this project is to produce a body of code which is
a lightweight framebuffer-based peer implementation for AWT and Swing.
The goal of this code is to remove the dependency on X or
other graphics layers such that graphics can be redirected to
a framebuffer (e.g. a raw buffer, VNC, etc.). This example
implementation will prefer pure-Java solutions, with public
extension points available to enter native resources as necessary.
See Project proposal: fbtoolkit.
Other answerers appear to assume that "full screen graphics in Java" necessarily means "a working implementation of AWT". This is, of course, not necessarily true, as it is perfectly possible (some would even say desirable) to use Java without AWT.
Cairo is a 2D graphics rendering library that can be used from Java, and can also be used without X11. It looks at first glance as though it should be possible to configure it for this scenario. You'll need to configure it to use OpenGL rendering, and provide a suitable non-X11 OpenGL implementation (e.g. MesaGL with the 'fbdev' device driver).
SDLJava is a Java port of the popular C SDL game development library. This also should be able to do what you ask for, although it doesn't seem to have been updated since 2005 so if you have any problems with it support may not be forthcoming.
As an alternative, you could always use some fairly simple C code to open and configure the framebuffer, and then use JNI to return the memory-mapped framebuffer as a direct-mode ByteBuffer, so you can draw to it directly.
To really display something graphical on the screen, yes. Bud there is a headless version of the JRE for just running it. You won't see any graphical output, but it will run.
Alternatively, you can log in remotely and use X forwarding to run the java code on the server but let the client handle displaying graphics.
On an embedded device, such as a Raspberry Pi, if you don't want to go through full X11 with standard Java AWT + Swing, then this https://github.com/ttww/JavaFrameBuffer project to write straight into the frame buffer seems interesting.
An alternative may be to use e.g. SWT on GTK, or Qt Jambi, to write into the Frame Buffer (both GTK and QT can directly use a FB without X11).
As I run Java programs (like DbVisualizer and OpenProj) on my computer, some UI components like buttons, images, check boxes, scrollbars, etc. show as blank boxes. Not rarely some of these components first appear normally when you open the program and then go blank as you mouse over them.
I have already updated JRE and video drivers and also tweaked JAVA_OPTS with -Dsun.java2d.noddraw=true;-Dsun.java2d.d3d=false;, as recommended in Java forums, but none of these proposed solutions have worked so far.
I don't believe this is an OS specific issue, since I checked some other PCs with the exact same configuration of OS (Windows Vista) and hardware and many of them don't present that problem.
A screenshot of this situation can be seen here:
Any ideas?
Those JAVA_OPTS must be separated by spaces and not semi-colons!
Connect to the application with jVisualVM and verify that the "JVM Arguments" section contains all your desired options.
While using windows basic theme I would often find numerous graphical glitches. Moving a window would create a trail behind itself over background windows and UI controls at times would not appear until moused over.
As already suggested, try using the windows aero theme and just turn off transparency if you don't like the aero look.
This does seem more like a graphics driver issue. Note how things that are missing are images (icons, checkboxes) which are drawn by transferring the bitmap data directly to the graphic card. The sun.java2d.noddraw=false and sun.java2d.d3d=false are more of a hacks in this case, really.
What I would do is:
check if I am using the latest version of Java (wouldn't hurt to switch to a 64-bit java if you are using a 64-bit system)
check your graphics drivers, make sure they are the latest version
check Windows service packs
Also try using changing the Look and feel; maybe this will help.
I suspect that disabling DirectDraw will fix this and your attempt to disable it was unsuccessful.
As noted by Ryan, the options appear to be formatted incorrectly. Remove the semicolons and put a space between, or better still, only use sun.java2d.d3d=false. The sun.java2d.noddraw flag was obsoleted Java SE6u10 and setting to true now has the same effect as setting sun.java2d.d3d=false. There is no need to set both.
The effect of the incorrect formatting can be seen in the code below:
public class WrongArgs {
public static void main(String[] args) {
System.out.println("sun.java2d.noddraw: " + System.getProperty("sun.java2d.noddraw"));
System.out.println("sun.java2d.d3d: " + System.getProperty("sun.java2d.d3d"));
}
}
Running this code with args: "-Dsun.java2d.noddraw=true;-Dsun.java2d.d3d=false;" produces:
sun.java2d.noddraw: true;-Dsun.java2d.d3d=false;
sun.java2d.d3d: null
Running with args "-Dsun.java2d.noddraw=true -Dsun.java2d.d3d=false"
sun.java2d.noddraw: true
sun.java2d.d3d: false
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.
how do I detect whether windows is in high contrast mode, or it displays large font or extra large font?
I need to provide accessibility support in my javascript.
Thanks.
See this post.
in high contrast mode on Windows, background images should be set to "none" and it also changes the background color. This should override any CSS stylesheet. So you can perform some javascript to detect it after initial rendering.
Edit: You said you actually want to do this in Java. This has been covered before on SO:
Turns out the win.highContrast.on
property was added in Java 1.4.1 for
this purpose.
Try SystemParametersInfo function with the following parameters:
SPI_GETHIGHCONTRAST
SPI_GETICONTITLELOGFONT
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.