Hi I'm working on a group project and the code works on my teammate's PCs but I keep hitting MacOS specific errors. And this time I seem to be stuck (no easily Googleable answer).
In a previous post I discovered I need "-Djava.awt.headless=true" as VM setting to properly run my simulation. Now when I try to spawn in some JFrame they are all met with a lovely "java.awt.HeadlessException" Exception because of that VM flag.
Trying to achieve
I want to be able to spawn those JFrames on my MacBook also.
The problem
I need -Djava.awt.headless to be both true and false at the same time for my program to run properly on Mac. Which if I understand my problem correcly, means I have a big problem on my hands.
EDIT: running it in a VM on my Macbook allowed me to run the project properly. This is far from an ideal fix. I'm still searching for a solution to this obscure problem.
What I tried
not running with the VM option: the problem described in previous post occurs. Thus this is not a viable option
running with the VM option: this throws a -Djava.awt.headless when creating a JFrame.
The best way to fix this may be by going back and solving your original problem a different way.
You must make sure that you are not initializing your BufferedImage in the main thread (GLFW thread), it MUST be done separately. It is hard to tell from your original question, but that looks like part of the cause there. Start a new thread to do the image processing instead.
See my solution and recommendation at the bottom of this answer for a quick summary, and also see here for someone else that had the same issue: Java Creating Instance of BufferedImage Freezes Program
A quick note on why your code works on Windows and not Mac: that is because both OS often run different implementations of openGL, and typically Mac can lag behind and miss out on a bunch of updates/changes that may solve problems like this one so that it doesn’t freeze when initializing a BufferedImage on the openGL thread.
If the above didn’t work then lets first look at what headless mode is. (Emphasis mine):
See link at bottom for full article and more info.
Headless mode is a system configuration in which the display device,
keyboard, or mouse is lacking. Sounds unexpected, but actually you can
perform different operations in this mode, even with graphic data.
Where it is applicable? Let's say that your application repeatedly generates a certain image, for example, a graphical authorization code
that must be changed every time a user logs in to the system. When
creating an image, your application needs neither the display nor the
keyboard. Let's assume now that you have a mainframe or dedicated
server on your project that has no display device, keyboard, or mouse.
The ideal decision is to use this environment's substantial computing
power for the visual as well as the nonvisual features. An image
that was generated in the headless mode system then can be passed to
the headful system for further rendering.
So when should headless mode be used:
On a machine that has no display device, keyboard, or mouse.
That is not you is it? However if that is you (LWJGL?), then lets look at how you can work with headless mode:
An image that was generated in the headless mode system then can be
passed to the headful system for further rendering.
This means that you should have a special piece of headless code that does your headless image stuff, but then passes the image back to a normal JFrame with a head.
So why does it fail for you:
Many components are affected if a display device, keyboard, or mouse
is not supported. An appropriate class constructor throws a
HeadlessException
Button
Checkbox
Choice
Dialog
FileDialog
Frame
Label
List
Menu
MenuBar
MenuItem
PopupMenu
Scrollbar
ScrollPane
TextArea
TextField
Window
Solution to the problem:
some classes, such as Canvas or Panel, can be executed in headless mode.
Perfect, so we just need to be careful what is used in headless mode. You asked how you can both use and not use headless mode, well rather than globally setting headless mode with VM option -Djava.awt.headless you can do it programmatically within your code using System.setProperty("java.awt.headless", "true"); where needed. A JFrame should be normal (not Headless), but you can spawn a JPanel as headless without issue.
I recommend:
You create a normal headed main thread with no VM option that spawns JFrames, and then use that main thread to spawn a new child thread and set your LWJGL bits in that thread to be headless, and that way you can run your LWJGL code without issue, and at the same time you can still have JFrames from your main thread. Remember to make sure that the Buffered image is not done in the main LWJGL/OpenGL thread.
Headless info source:
http://www.oracle.com/technetwork/articles/javase/headless-136834.html
Related
I have some java code that I am trying to interface with from a flutter application (in-process) using the jvm from a native plugin. The problem that I'm having occurs specifically under Linux with flutter- it is not displaying/rendering any text on the java ui components e.g. button labels, text in text-fields.
When I run this code under windows or when I run java code directly with Linux everything seems to be as intended. This suggest this bug is very specific to flutter/linux combination.
I've created an issue at the flutter repository https://github.com/flutter/flutter/issues/105824 to cover some more details with a sample application.
I've tried following the awt debug tips outlined on https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/awt001.html
Configured the loggers to capture any messages of warning or higher
Configured the uncaught exception handler
Configured the sub.awt.noisyerrorhandler
I'm wondering if there's anything that could explain this behavior? None of above have really given me any insights.
Edit:
One of the things that seemed off to me is that the focus rectangle isn't computing it's dimensions. This made me question if the problem is on the java side.
A JButton dervives from JAbstractButton which derives from JComponent
The ui of JComponent seems mostly drawn by ComponentUI - in case of JButton this would be BasicButtonUI
so somewhere around this line it means https://github.com/openjdk/jdk17/blob/74007890bb9a3fa3a65683a3f480e399f2b1a0b6/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicButtonUI.java#L338 the rectangle doesn't have measurements.
Haven't gotten any further as this yet.
How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.
There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.
Options for window managers which can do this include KDE or twm-kiosk.
(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)
Edit:
In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:
You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).
Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.
As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.
Environment: Windows 7, JRE 8.65, observed with both yEd 3.14 and GanttProject 2.7.1 (also previously observed on Win XP.)
Can the program's main window take focus (not auto-raise) without being atop other windows and without clicking in it? (nothing found in 917 results from a StackOverflow search on the words "Java" "window" and "focus", though I was getting bleary-eyed by the end.)
The problem is that when I move the pointer into or across the program's window, that window does not activate, though it activates the icon in the "task bar" (which is auto-hidden.) It is clear that the program recognises the pointer's existence and focus change, but the main window never actually takes the pointer (i.e. the main window remains inactive, and requires that I click in it to activate it; which raises it, which is exactly the behaviour I try to avoid with F-F-M.)
This is more troublesome because when the icon in the task bar activates, the task bar covers a chunk of my screen and won't go away until the main program window is activated by clicking in it. Simply moving the mouse from one place to another on the screen has about a 30% probability of touching (and half-activating) one of these program windows, forcing me to locate the window, click in it, minimise it, then get back to what I really was trying to do. (Yes, my "desktop" is a jumble, but everything has its place and normally I can rapidly navigate among the dozen or so windows that are truly useful.)
Thanks for any pointers or advice. (Though suggestions that I change my behaviour probably won't be followed.)
This problem occurred to me as well. The only workaround I got so far is using JRE 6 if possible since this annoying behavior started with JRE 7.
I've just started making my first GUI application in Java and I decided to use the NetBeans IDE to do it. I think its working fine so far, except for one problem; it seems to be slow updating the content of a window.
Even in very simple windows with few controls I find that when - for example - closing or resizing a window, I get the normal window border working properly but the inside is completely see through for a second.
It's not the biggest deal in the world, I just find it mildly annoying.
EDIT: I've tried the HelloWorldSwing from the official Java tutorial but I have the same issue, only now, when resizing, instead of being transparent, the new area of the window is black until the contents updates.
You should ensure that all of your GUI updates are performed in the Event Dispatch Thread, and that any other long running tasks are performed in worker threads. If you have long running tasks running in the EDT, your GUI will feel sluggish. Take a look at this tutorial for concepts on Swing Threading.
In the absence of any technical problems with your app, this could simply be JVM warmup effects. Do updates speed up if you resize the window a few times?
This could be a Java2D hardware accelleration issue. Is your 3D graphics card driver fully updated?
We have a Java Applet built using AWT. This applet lets you select pictures from your hard drive and upload them to a server. The applet includes a scrollable list of pictures, which works fine in Windows, Linux and Mac OS X 10.5. We launch this applet via Java Web Start or within a web page.
Our applet does not behave properly in Mac OS X 10.4, regardless of the version of Java (1.4 or 1.5). You can find a screenshot of the incorrect behaviour, when scrolling, here:
http://www.lavablast.com/tmp/ui_error.png
Simply put, sometimes when scrolling the pictures end up overlapping the header or footer of the application. This behaviour does not occur on other platforms. On Mac OS X 10.4, it shows the pictures in the incorrect location when scrolling, which would not be so bad if it refreshed the screen after painting the image at that location. However, it does not appear that the application knows it painted it incorrectly and thus does not refresh.
If the window is minimized, resized or even moved, the application is refreshed and the incorrectly positioned elements vanish and the application resumes normally. I spent quite some time trying to force a refresh of the background image unsuccessfully. (the repaint the image directly, repaint all children of a few panels, etc. ) Thus, I am looking for any tips that would help me resolve this problem under Mac OS X 10.4 or, in the worst case, simply simulate a full applet refresh.
Until recently, everything was compatible with Java 1.1 but this has changed in a few locations which now require 1.4. I don't feel these changes created the issue, I am just providing this as extra information. If you are interested in implementation details of the scroll panel, I will investigate, but I am assuming this is a common platform bug for which workarounds must be known.
To replicate the problem, open the following Java Web Start application:
http://www.lavablast.com/tmp/opal-webstart.php.jnlp
Select a folder containing lots of images and play with the scrollbar. At some point (fairly quickly), you should get the refresh problem.
Edit: I followed the first suggestion here and replaced all my controls that feature background images with a Swing equivalent and the issue is still there. (Plus, there are numerous other fixes I would need to do to do a complete change). Any other ideas? A simple one line of code that forces a full refresh would be great :)
Edit2: The main thread creates the panels and launches X threads. Using an observer/notifier pattern, the threads complete and notify the main control, which adds a panel to the page. This is done via an EventQueue.invokeLater which, unless I am mistaken, should run on the right thread. The issue is at its most severe when scrolling even if no extra threads are running (as during the loading).
It does look like mixing lightweight (usually Swing) and heavyweight (AWT) components together. Moving to Swing you need to replace every last AWT component Swing equivalents (hint: avoid import java.awt.*).
Threading is often a potential problem for odd bugs. Swing components must always be used on the EDT (use java.awt.EventQueue.invokeLater). AWT is thread-safe is theory, but not in practice - also restrict usage to the EDT.
As you already require Java 1.4 you should consider some small changes to take into use SWING GUI instead, it solved our Applet refresh issues with AWT. (Mac, Linux etc)
If you have e.g. Panel, you need to replace it with JPanel etc.
You need this:
import javax.swing.*;