I have a main class which should call a JavaFX application (SimpleSun) to get Information from the user. Currently I create an Object of the JavaFX class and start it, but that doesn't seem to work. Does someone see the mistake in my work?
Here's my code and exception:
Main.java:
package ch.i4ds.stix.sim;
import ch.i4ds.stix.sim.grid.config.Configuration;
import ch.i4ds.stix.sim.grid.config.ConfigurationFromFile;
public class Main{
Configuration config;
public static void main(String[] args) {
ConfigurationFromFile config = new ConfigurationFromFile();
SimpleSun ss = new SimpleSun(config);
ss.show();
}
}
SimpleSun.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import ch.i4ds.stix.sim.grid.config.Configuration;
import ch.i4ds.stix.sim.grid.config.ConfigurationFromFile;
public class SimpleSun extends Application{
private Stage primaryStage;
Configuration configuration;
public SimpleSun(ConfigurationFromFile config) {
this.configuration = config;
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Simple Sun - Alpha");
System.out.println("Test");
try {
// Load the root layout from the fxml file
FXMLLoader loader = new FXMLLoader(
Main.class.getResource("view/RootLayout.fxml"));
BorderPane rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
}
public void show(){
launch();
}
}
Exception:
Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class ch.i4ds.stix.sim.SimpleSun
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.access$000(Unknown Source)
at com.sun.javafx.application.LauncherImpl$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodException: ch.i4ds.stix.sim.SimpleSun.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getConstructor(Unknown Source)
... 4 more
You must provide a constructor with no arguments when you extend application. So you could do something like:
public class SimpleSun extends Application {
private Stage primaryStage;
Configuration configuration;
public SimpleSun() {
this.configuration = Main.getConfig();
}
//...
and in your Main class:
public static Configuration getConfig() { return new ConfigurationFromFile(); }
Alternatively you can pass String parameters to the class with launch(args) and get them back in the SimpleSun class with getParameters().
Related
This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 9 months ago.
I'm currently trying to start coding an app with IntelliJ and JavaFX, I have the following code :
package main.gui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.net.URL;
public class MainMenu extends Application {
#Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
URL url = getClass().getResource("hello-view.fxml");
System.out.println("URL = " + url);
Parent root = FXMLLoader.load(url);
Scene scene = new Scene(root,1920,1080);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
}
My file structure :
src/main/gui/MainMenu.java
src/main/gui/hello-view.fxml
And I get this exception :
Exception in Application start method
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1082)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3324)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3287)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3255)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3227)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3203)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3196)
at main/main.gui.MainMenu.start(MainMenu.java:13)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
... 1 more
It outputs : URL = null
I've tried a lot of stuff that I've found on this site but without success...
Thank in advance for your help :)
To add a little more detail : I'm using Maven and I created the project with the
JavaFX project creation tool provided with IntelliJ.
I made it work by simply putting my fxml file into a ressources folder (src/main/resources) as suggested by #MatteoNNZ.
I tweaked a little bit the code to have the following :
package main.gui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.net.URL;
public class MainMenu extends Application {
#Override
public void start(Stage stage) throws Exception {
URL url = getClass().getClassLoader().getResource("hello-view.fxml");
System.out.println("URL = " + url);
Parent root = FXMLLoader.load(url);
Scene scene = new Scene(root,1920,1080);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
}
Obviously it could be simplified like this :
#Override
public void start(Stage stage) throws Exception {
// URL url = getClass().getClassLoader().getResource("hello-view.fxml"); |
// System.out.println("URL = " + url); | Remove these 3 lines
// Parent root = FXMLLoader.load(url); |
Scene scene = new Scene(FXMLLoader.load(getClass().getClassLoader().getResource("hello-view.fxml")),1920,1080);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
but it is very ugly.
Thank you everyone for your help and very quick answers :) .
I have a main class which should call a JavaFX application (SimpleSun) to get Information from the user. Currently I create an Object of the JavaFX class and start it, but that doesn't seem to work. Does someone see the mistake in my work?
Here's my code and exception:
Main.java:
package ch.i4ds.stix.sim;
import ch.i4ds.stix.sim.grid.config.Configuration;
import ch.i4ds.stix.sim.grid.config.ConfigurationFromFile;
public class Main{
Configuration config;
public static void main(String[] args) {
ConfigurationFromFile config = new ConfigurationFromFile();
SimpleSun ss = new SimpleSun(config);
ss.show();
}
}
SimpleSun.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import ch.i4ds.stix.sim.grid.config.Configuration;
import ch.i4ds.stix.sim.grid.config.ConfigurationFromFile;
public class SimpleSun extends Application{
private Stage primaryStage;
Configuration configuration;
public SimpleSun(ConfigurationFromFile config) {
this.configuration = config;
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Simple Sun - Alpha");
System.out.println("Test");
try {
// Load the root layout from the fxml file
FXMLLoader loader = new FXMLLoader(
Main.class.getResource("view/RootLayout.fxml"));
BorderPane rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
}
public void show(){
launch();
}
}
Exception:
Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class ch.i4ds.stix.sim.SimpleSun
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at com.sun.javafx.application.LauncherImpl.access$000(Unknown Source)
at com.sun.javafx.application.LauncherImpl$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodException: ch.i4ds.stix.sim.SimpleSun.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getConstructor(Unknown Source)
... 4 more
You must provide a constructor with no arguments when you extend application. So you could do something like:
public class SimpleSun extends Application {
private Stage primaryStage;
Configuration configuration;
public SimpleSun() {
this.configuration = Main.getConfig();
}
//...
and in your Main class:
public static Configuration getConfig() { return new ConfigurationFromFile(); }
Alternatively you can pass String parameters to the class with launch(args) and get them back in the SimpleSun class with getParameters().
I'm trying to run a JavaFx OSGi module, but I keep getting the error:
org.osgi.framework.BundleException: Unable to resolve OSGiDmHelloWorldProvider [7](R 7.0): missing requirement [OSGiDmHelloWorldProvider [7](R 7.0)] osgi.wiring.package; (osgi.wiring.package=javafx.application) Unresolved requirements: [[OSGiDmHelloWorldProvider [7](R 7.0)] osgi.wiring.package; (osgi.wiring.package=javafx.application)]
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4112)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2118)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
This is how I load and start the modules:
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
import java.io.File;
import java.util.*;
public class Launcher {
private static String[] libs = null;
private BundleContext context;
private Launcher() {
FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
Map<String, String> config = new HashMap<String, String>();
config.put("osgi.console", "");
config.put("osgi.clean", "true");
config.put("osgi.noShutdown", "true");
config.put("eclipse.ignoreApp", "true");
config.put("osgi.bundles.defaultStartLevel", "4");
config.put("osgi.configuration.area", "./configuration");
// automated bundles deployment
config.put("felix.fileinstall.dir", "./dropins");
config.put("felix.fileinstall.noInitialDelay", "true");
config.put("felix.fileinstall.start.level", "4");
config.put(Constants.FRAMEWORK_BOOTDELEGATION, "javafx.*,com.sun.javafx.*");
config.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_APP);
Framework framework = frameworkFactory.newFramework(config);
try {
framework.init();
framework.start();
} catch (BundleException e) {
e.printStackTrace();
}
context = framework.getBundleContext();
Bundle OSGiDmHelloWorldProvider = install("OSGiDmHelloWorldProvider");
try {
OSGiDmHelloWorldProvider.start();
} catch (BundleException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Launcher();
}
private String[] getLibs() {
if (libs == null) {
List<String> jarsList = new ArrayList<String>();
File pluginsDir = new File("libs");
System.out.println("PATHS : " + pluginsDir.getAbsolutePath());
for (String jar : pluginsDir.list()) {
jarsList.add(jar);
}
libs = jarsList.toArray(new String[jarsList.size()]);
}
return libs;
}
protected Bundle install(String name) {
String found = null;
for (String jar : getLibs()) {
if (jar.startsWith(name)) {
found = String.format("file:libs/%s", jar);
System.out.println(found);
break;
}
}
if (found == null) {
throw new RuntimeException(String.format("JAR for %s not found", name));
}
try {
return context.installBundle(found);
} catch (BundleException e) {
e.printStackTrace();
}
return null;
}
}
The OSGiDmHelloWorldProvider Activator class:
import com.bw.osgi.provider.able.HelloWorldService;
import com.bw.osgi.provider.impl.HelloWorldServiceImpl;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ProviderActivator implements BundleActivator {
Logger logger = LoggerFactory.getLogger(ProviderActivator.class);
Stage stage;
private ServiceRegistration registration;
BundleContext bundleContext;
#Override
public void start(BundleContext bundleContext) throws Exception {
registration = bundleContext.registerService(
HelloWorldService.class.getName(),
new HelloWorldServiceImpl(),
null);
Platform.runLater(new Runnable() {
#Override
public void run() {
stage = new Stage();
BorderPane pane = new BorderPane();
Scene scene = new Scene(pane, 400, 200);
pane.setCenter(new Label("This is a JavaFX Scene in a Stage"));
stage.setScene(scene);
stage.show();
}
});
System.out.println("STAGE CALLED !!!");
}
#Override
public void stop(BundleContext bundleContext) throws Exception {
registration.unregister();
logger.info("Set4Jfx Bundle: stop()");
Platform.runLater(new Runnable() {
#Override
public void run() {
stage.close();
}
});
}
}
How can I load a module that uses JavaFx in a Maven OSGi application?
The error message means that your bundle imports package javafx.application, and no bundle exports that package. Therefore the import cannot be resolved.
I note that in your launcher code you try to set bootdelegation to javafx.*. That might allow the class to be loaded from the boot classpath if your bundle ever got as far as running, however it cannot get that far because of the unresolved import.
If you intend for the JavaFX classes to be loaded from the boot classloader then you should remove the package import from your own bundle. You would also have to arrange for the JavaFX classes to actually be provided by the boot classloader, since AFAIK they are normally only visible from the extension classloader.
However a better solution would be leave the import alone, and arrange for the javafx.application package to be exported from a bundle. That could be done from the system bundle using Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA.
Update
You should probably look at the Drombler FX tool/framework from #Puce, since it sounds like he has already done a lot of these setup tasks. However I felt that his answer didn't directly address your question about why your code was failing.
I've released some first versions of Drombler FX - the modular application framework for JavaFX based on OSGi and Maven (POM first).
It takes care of initializing JavaFX and OSGi.
Maybe you find it useful. The application framework is Open Source and the code is available on GitHub.
There is also a tutorial with a Getting Started trail.
i wrote a program in netbeans with RMI that client has error
error :
java.rmi.UnmarshalException: error unmarshalling return; nested
exception is: java.lang.ClassNotFoundException: rmiserver.Message
(no security manager: RMI class loader disabled) at
sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
but sever does not any error!
interfaace code:
package rmiclient;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Message extends Remote {
void sayHello(String name) throws RemoteException;
}
interface implementation is:
package rmiserver;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class MessageImpl extends UnicastRemoteObject implements Message {
public MessageImpl() throws RemoteException {
}
#Override
public void sayHello(String name) throws RemoteException {
System.out.println("hello "+name);
}
}
server code is:
package rmiserver;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Main {
private void startServer(){
try {
// create on port 1099
Registry registry = LocateRegistry.createRegistry(1099);
// create a new service named myMessage
registry.rebind("myMessage", new MessageImpl());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("system is ready");
}
public static void main(String[] args) {
Main main = new Main();
main.startServer();
}
}
client code is:
package rmiclient;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Main {
private void doTest(){
try {
// fire to localhost port 1099
Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);
// search for myMessage service
Message impl = (Message) myRegistry.lookup("myMessage");
// call server's method
impl.sayHello("edwin");
System.out.println("Message Sent");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Main main = new Main();
main.doTest();
}
}
thanks :).
In your stacktrace:
java.lang.ClassNotFoundException: rmiserver.Message
but as per data you have provided, your Message interface is declated with package package rmiclient; and You haven't created any rmiserver.Message class.
Correct the package name.
I have two package. rmiclient and rmiserver. that in rmiclient are "message" and "main" . in rmiserver are "message" and "main" and "messageimpl"
That's your problem. This doesn't satisfy the contract. You can't just copy Message to another package and expect to have it be treated the same as the original. The remote stub implements the same remote interfaces that the remote object does. Not another interface with the same name in another package.
You have to deploy rmiserver.Message to the client. Just like the error message says, really.
I have designed a UI in javafx scene builder, which has a simple button in stackpane.And I have named the controller class as simplecclass. I have saved the fxml as simple.fxml.
I have created a controller class in netbeans, which simply prints some msg on clicking the button.
In the NewFXBuilder java , I have loaded simple.fxml. Please find below the NewFXBuilder.java code.
package javafxapplication2;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXMLLoader;
public class NewFXbuilder extends Application {
#Override
public void start(Stage primaryStage) {
try {
StackPane page = (StackPane) FXMLLoader.load(NewFXbuilder.class.getResource("simple.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("FXML is Simple");
primaryStage.show();
} catch (Exception ex) {
Logger.getLogger(NewFXbuilder.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
Application.launch(NewFXbuilder.class, (java.lang.String[])null);
}
}
My simple.fxml,simplecclass.java and NewFXbuilder.java all resides in the same folder javafxapplication2.
while running NewFXBuilder.java, but it gives me the following error.
javafxapplication2.NewFXbuilder start
SEVERE: null
javafx.fxml.LoadException: java.lang.ClassNotFoundException: simplecclass
javafxapplication2.NewFXbuilder start SEVERE: null
javafx.fxml.LoadException: java.lang.ClassNotFoundException:
simplecclass
Looks like a problem in the FXML file. Make sure you import simplecclass in the FXML file.
The mistake I did was forgotten to add java packagename in the controller class name field in scene builder. It should have been packagename.simplecclass but I gave simplecclass alone,which is a mistake.