简体   繁体   中英

passing a parameter into a javafx class

I am writing a java class extending the application class of javafx and am trying to pass an object into the constructor like so:

public class SceneWindow extends Application{
    
    private int x;
    private int y;
    private int textX;
    private int textY;
    private static ImagePattern img;
    public String title;
    private ArrayList<EventHandler<MouseEvent>> events = new ArrayList<EventHandler<MouseEvent>>(); 
    private Text mainDialogue = new Text(0, 0, "test");
    private int eventIndex = 0;
    
    
    public SceneWindow(SceneManager sm){ 
        x = sm.getWindowX();
        y = sm.getWindowY();
        
        textX = sm.getTextX();
        textY = sm.getTextY();
        
        img = sm.getBackground();
        title = sm.getTitle();
        events = sm.getEvents();
        mainDialogue.setText(sm.getText());
        
    }

I am creating an instance of SceneWindow like this:

SceneWindow sw = new SceneWindow(sm);

with sm being a SceneManager object.

However this is not working. I have read elsewhere that this is because you are unable to have a non-zero parameter in a javafx constructor.

This is the error message I am getting:

Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class application.SceneWindow
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:891)
    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.NoSuchMethodException: application.SceneWindow.<init>()
    at java.base/java.lang.Class.getConstructor0(Class.java:3585)
    at java.base/java.lang.Class.getConstructor(Class.java:2271)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:802)
    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

How can I get around this?

Read the JavaFX Application javadoc :

The Application subclass must be declared public and must have a public no-argument constructor.

Additionally, study the application lifecycle information in the linked javadoc.

You should only have a single application instance within the VM and that will be created by the application launch sequence which invokes the no-args constructor.

Therefore creating an additional constructor for the application which has arguments is pointless at best as it should never be called.

Why you shouldn't manually create a new application instance

If your parameterized constructor were manually called via new , yes it would create a new application instance. But then you would have two instances in the VM, one created manually by you, and one automatically created by the launcher, and they would have different states of initialization and one would be managed by the JavaFX lifecycle and one (the one you manually created) would not, which would just be an unnecessarily confusing and error-prone situation to create => you should never manually create a JavaFX Application instance.

Command line args

Note: You can provide a static main method that has a standard String[] args argument list, and those parameters will be available to the application instance via getParameters() , so it is possible to pass arguments to the application instance, but those arguments are a completely different thing then what you are trying to do as they are just command line string arguments, not arbitrary Java object references. The arguments are passed as parameters to the application class instance via the launch(appClass, args) method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM