I’m moving from Swing to JavaFX2.0. I have an internal service with various JFrame windows to display/alter internal parameters. I have a menu with buttons. Each button kicks off one of the JFrame windows as such:
new ASvr().setVisible(true);
Works fine. Now going to JavaFX2.0: Each “window” is an independent FXML application. The independent FXML applications run as standalone applications when the service is remote using RPC to communicate with the service. This is the internal version where the “windows” are part of the same JVM.
The Menu starts with application.launch(). There can only be one launch() in the JVM so I can’t use launch() for the independent FXML applications. After much trial and error (mostly error) what I’ve come up with is:
new ASvr().start(new Stage());
Works fine, I think. Since I’m new to JavaFX I could be missing something which will ruin this solution. Calling start() myself, not from a launch(), may have nasty side effects. I can’t use a new ProcessBuilder and put each application inside a new JVM since I need direct access to references within the internal service.
My questions: Is there a preferred way to have several independent (need to run as standalone without alteration) FXML application scenes running within a JVM? Do you see any potential problems with what I did?
I would not recommend calling start(...) yourself. The launch(...) method does a lot of complex housekeeping, such as starting the FX toolkit and the FX Application Thread, instantiating the application class, and then invoking start(...) on the FX Application thread.
You should basically think of start(...) as the equivalent of the main(...) method for a JavaFX application, and the Application subclass as the "main-class", not the JFrame subclass. (Indeed, in Java 8, if your class is a subclass of Application it can be launched directly by the JVM without even having a main(...) method.)
Once you have created your single start(...) method (again, just think of it as the replacement for your single main(...) entry point from a "regular" Java application), then you can show the contents of an FXML file with the idiom
Stage stage = new Stage();
stage.setScene(new Scene(FXMLLoader.load(fxmlResource));
stage.show();
(Of course, there are variations on this, especially if you need access to the controller, but you get the idea.)
You could if you wanted create subclasses of Stage, in the old swing style of creating JFrame subclasses, and let the constructor of the Stage subclass load its FXML and set its own scene. Then you could use essentially the same idiom as you used in Swing:
new MyStageSubclass().show();
Notice again how the analogue of a JFrame subclass is a Stage subclass, not an Application subclass.
Related
I'm following this example for a queued hosted service to add this to an ASP.NET Core application, and it's not clear to me where StartMonitorLoop should be called. I ended up modifying it to be EnsureMonitorLoop, added a check so that it's the call to Task.Run is only made once, added a MonitorLoop parameter to constructor for my API controller, and called EnsureMonitorLoop from there. It smells kind of funny to me that the API controller constructor should be kicking off monitoring the queue. The example Program.cs seems is very different from the one generated for me by Visual Studio. Mine uses the WebHost.CreateDefaultBuilder(args).UseStartup<Startup> approach. That is where they call StartMonitorLoop.
Where is the correct place to call StartMonitorLoop, and why? Thanks!
The docs aren't super clear here, but MonitorLoop is not actually part of this. It's an example service for use in a console app, simply to demonstrate how the queued background worker works. You can take some inspiration from this class for your app, but the concept of StartMonitorLoop doesn't apply to ASP.NET Core at all.
Just to be a bit more clear: in actual practice you would inject IBackgroundTaskQueue into a controller class, for example, and then add some task to that, just like MonitorLoop does (without all the key input jazz). You wouldn't actually have MonitorLoop or anything like it though.
I got error when execute code. I think it's not related to code. something is missing.
java.lang.IllegalStateException: Problem in some module which uses Window System: Window System API is required to be called from AWT thread only, see http://core.netbeans.org/proposals/threading/
You have flagged your post with JavaFX, so I assume you are talking about a JavaFX application. Every GUI update in the JavaFX-world is done on the JavaFX application thread. Your exception however indicates that you are using some AWT code in your program which has a different requirement. It must be run on AWT thread. So, the first thing you have to do is find out what this code is and then you have to make sure to call it on the right thread. You can use Platform.runLater() to put something on the JavaFX thread and SwingUtilities.invokeLater() to put something on the AWT thread.
I'm trying to migrate a program from java 8 to java 9.
In my program I found the following code.
//Run JavaFX Application Thread/Toolkit
PlatformImpl.startup(() -> {
});
It tries to start the JavaFX Toolkit
Unfortunately, the PlatformImpl.startup is no longer supported in java 9.
Which substitute is there for it?
How can I start the JavaFX Toolkit?
Thank you
The startup() method is one of the methods that was promoted from the non-public class PlatformImpl to the public API Platform class in the Java 9 release. It is now fully documented in the API documentation.
Thus the equivalent call in Java 9 is
Platform.startup(() -> { });
Note that the use cases for this method are fairly rare, and the API docs go to some lengths to emphasize this:
In general it is not necessary to explicitly call this method, since it is invoked as a consequence of how most JavaFX applications are built.
...
As noted, it is normally the case that the JavaFX Application Thread is started automatically. It is important that this method only be called when the JavaFX runtime has not yet been initialized. Situations where the JavaFX runtime is started automatically include:
For standard JavaFX applications that extend Application, and use either the Java launcher or one of the launch methods in the Application class to launch the application, the FX runtime is initialized automatically by the launcher before the Application class is loaded.
For Swing applications that use JFXPanel to display FX content, the FX runtime is initialized when the first JFXPanel instance is constructed.
For SWT application that use FXCanvas to display FX content, the FX runtime is initialized when the first FXCanvas instance is constructed.
When an application does not follow any of these common approaches, then it becomes the responsibility of the developer to manually start the JavaFX runtime by calling this startup method.
Calling this method when the JavaFX runtime is already running will result in an IllegalStateException being thrown - it is only valid to request that the JavaFX runtime be started once.
So, while you are in the process of making the changes you need to update your application to be Java 9 compatible, you might want to carefully consider if you need to call startup() at all; maybe there is a more standard and robust approach to starting your JavaFX application anyway.
I have a requirement for creating a singleton for QTimer across my program. The problem is that when the QTimer object times out, I get a segmentation fault.
I am currently using qt creator and the debug stack shows the crash on activation() call of the moc_ class for the same on the timeout event.
My current project uses the component architecture template(basically something like a star structure where multiple components communicate via a central component) and I intend to use the class over multiple components.
I originally created the same code on a separate project using the basic template where the code was working.
Hence, this brings me to my question; are QObjects not allowed to exist as singletons over multiple components in a component structure?
I am writing a plugin for another application. I want to support the plugin on multiple platforms, so I am strongly considering using Qt.
The plugin needs to be able to show some basic GUI. The plugin interface does not in any way handle GUI - it is just a simple DLL/shared library specified with a C-header file.
Can I use Qt inside such a shared library? The calling application might or might not be using Qt itself. Any hints on what to do? Do I need to run a QApplication event-loop in a separate thread? Or can I just call the event-loop myself while waiting for input? (I only need modal dialogs).
I don't think it is possible because you need to create the QApplication eventloop in the main thread.
Note that QCoreApplication::exec()
must always be called from the main
thread (the thread that executes
main()), not from a QThread. In GUI
applications, the main thread is also
called the GUI thread because it's the
only thread that is allowed to perform
GUI-related operations.