In Eclipse, I created one CN1 project and one normal Java project, which depends on the former. The latter contains some utilities (e.g., source code generation) and some JUnit tests. I use the following simple hack:
CodenameOneImplementation impl = new JavaSEPort();
Util.setImplementation(impl);
Display.init(impl);
It works, but there's a fullscreen window shown and the program doesn't terminate when main is done. I know, that it's the normal behavior for GUI applications, but I don't need any GUI as I only initialized Display, in order for Display#getResource to work.
How can I get rid of the window (or at least make it small)?
How can I terminate the program without having to call System.exit (i.e., something like running the event handling thread as daemon)?
Is there more to set up?
Use something like this:
JavaSEPort.setDefaultInitTarget(new JPanel());
This would draw the UI of the display into the blank JPanel.
About exiting the app you would need to use System.exit(0) as the EDT loop and native GUI loop are running. You can stop the EDT but that might not work well for the desktop port so just using exit is easy and common practice.
Related
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
I'm building a multi-window and multi-module simulation application, and I use JavaFX for GUI.
From what I understood, to make a JavaFX project run, you need to run Application.launch( MyApplicationSubclass.class ) and use the primary stage given in the start(Stage primaryStage) method to get started. Everything in the start method and beyond happens in a JavaFX thread.
My app is a multi-moduled application. Today, a Main class bootstraps the program and launches several modules (which are distinct Maven modules), including the one in charge of the GUI. In the beginning (when I designed the current architecture), I planned to create only one window. So, once loaded, the GUI module would make the Application.launch( MyOnlyMainWindow.class ) call, and everything would work fine.
Today, I'd like to add a console window, launched before any module, and used to "live-log" the application (by redirecting the System.out stream, between other things, into a TextFlow). But with the architecture previously described, it's impossible, because if I want ot keep the Application.launch() call in the GUI module, then I can't make it in the Console window, which is not a part of the GUI module. It would also be impossible to add another GUI module that would manage another set of window.
So I can think of two and a half ways to solve this:
Centralize, somehow, the Application.launch() call so that it is available to every class that would need it. I don't know how to do it though.
Change the Main class to heritate from javaFx Application class. But wouldn't that make me execute all my module instanciations into the JavaFX Thread? I would guess this is a bad way of doing things. Or even, if I decide to create other threads for module instanciation, those threads would have been created in the JavaFX thread.
(Use Swing for the Console Window, though it does not actually solve my problem a viable way... What if I need to create another window in another GUI module?)
What would be a viable way of creating and managing a multiple window application with JavaFX? How could I, for instance, centralize the JavaFX Application.launch() calls?
Or, in other words
Is it a good practice to decentralize the JavaFX Application implementation in a module and launch the module from the main() class, or is it better to implement it in the main() class, even if I try to make my program modular?
Suppose I have a set of codes to display a JFrame, a JPanel, and a JLabel. This works fine if I run it as a script file. It just shows a tiny window with a label that says "A label" exactly like you would expect:
frame = javax.swing.JFrame('Test');
panel = javax.swing.JPanel();
label = javax.swing.JLabel('A label');
panel.add(label);
frame.add(panel);
frame.setDefaultCloseOperation(javax.swing.JFrame.HIDE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
The problem comes when I compile this as an exe file with the deploytool. It will compile and I can run the program, but the frame will show up for about 3 seconds or so then disappear. If I run from inside Matlab with !main.exe, there is no error message when the window disappears (I don't want to say it crashes because there is no error message). Neither is there one if I run the executable from the Windows command prompt (same results -- shows for a few seconds and then crashes).
Any ideas what is going on here? I can compile other files just fine. Is the problem because I included the javax.swing elements?
Many thanks for your help.
UPDATE
This feels like a really cheap hack, but having a while loop that pauses Matlab as long as the JFrame is open does the trick. So now the question is, is there a better way to do this?
The problem is probably that your main M-code function finishes executing, and since there are no figures up, Matlab decides to exit. In a Java Swing program, what would happen is that things would keep going until all the Swing windows are closed or you explicitly terminate the program. Since this is a Matlab program, the layer that's "in control" is the Matlab handle graphics layer, so you need to either have the main function executing or a figure up. (In interactive Matlab, it'll keep running as long as you have the IDE up, but there's no IDE in a compiled Matlab program, so when its work is done, it exits.)
The "Right Thing" to do from MathWorks' perspective is to probably buy the Matlab Builder JA toolbox, build the Matlab part of your program in to a Java library, include that in a main program which you write in Java. That way the Java layer is "in control" of the main execution sequence, and the "stay running as long as there are Java windows open" logic you're expecting will be in effect.
If you want to hack this to make it work in your current program structure, your invisible figure window might be a good one. Though you will need to make it Visible to have it work; invisible figures don't count for keeping a Matlab GUI running. You may be able to hide it from the user by changing its position to move it entirely off the user's screen.
Then you need to terminate the program somehow. Some part of your code is going to know when the program should end. That sounds like it's the Java part of your code. From there, you could just call java.lang.System.exit(). If you need to do Matlab-layer stuff, you could exit from M-code by communicate the "it's time to exit" back to your Matlab code, which could then call exit() or close that figure. You could do this by setting a public class variable in one of your Java classes, and have a Matlab timer object that checked that variable every 500 milliseconds or so.
If the condition that ends the program is that all your Java Swing windows get closed, that's a little tougher. Because the Matlab figure window itself is a Java AWT or Swing window, so as long as that's open you're not getting down to zero windows. What you could do is have that Matlab timer, instead of looking for a class variable, check the list of open Java windows and see if the Matlab figure is the only one left, and if so, close it or exit explicitly.
I am making an application which works with a game that runs in an applet (i didn't make the game, i am just making things for it, in this case, the launcher), but the applet is not coded very neatly so it has calls to System.exit(int).
I need the launcher to stay open on the event of the game crashing or the user clicking the quit game button and attempting to call System.exit(int) so the only way i can do this is by making a SecurityManager that functions like System.exit(int) go to check with it to see if it's allowed to exit the Java VM, if it's not, it will throw an exeption.
The second part of the solution for keeping the launcher open is by creating an UncaughtExceptionHandler so it can ignore the exception thrown by trying to exit; By implementing this, i can also have the launcher notify the user of a bug in the launcher when it's not the exiting exception (if it's something else, that's not supposed to be there so it'll result in a bug report).
Now, the actual problem that this question is about is how can i make the SecurityManager aware of if the game or my launcher that is trying to call System.exit(int)? I still need my launcher to be able to exit when it wants to, the game is just what i want to restrict.
Someone suggested using ProtectionDomain to detect what code base is running the code but i don't understand how this is implementable. You don't have references to classes in the SecurityManager.
I am currently working on a research project for a University in which I am doing GUI interactions with my database and launching an external program based on the data. I'm using runtime commands (once the OS is detected) to launch that external program with the selected data.
My question is how can I embed an external program's GUI inside a Java frame, if that is even remotely possible?
Given the clarifying comments on the question, the short answer is "no, you can't do that".
Java cannot display a native program's GUI within a JFrame, even if the target program was actually architected to allow it's GUI to be presented within another program's frame.
Are you using a console application? You have to intercept its stdout to do it correctly. So you can show the text that the 3rd party application is outputting in an UI control that you can put into JFrame.
It depends from the application you want to embed to the JFrame, but you can try to use jawt:
https://docs.oracle.com/javase/9/docs/specs/AWT_Native_Interface.html
You will be able to get the native OS specific window handle and can draw on top of it, or can you use it as a container. Note that only HW components are supported, so you will need to add Panel/Canvas to the JFrame and then use that for your native app.
This is similar to this question:
Native JNI/JAWT Swing application runs successfully on Java 6, but fails on Java 7 (64-bit Windows 7 OS)
Use java.lang.Process or java.lang.Runtime.exec.
http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html