【问题标题】:passing a parameter into a javafx Application class将参数传递到 javafx 应用程序类
【发布时间】:2022-01-14 00:24:00
【问题描述】:

我正在编写一个扩展 javafx 应用程序类的 java 类,并尝试将对象传递给构造函数,如下所示:

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());
        
    }

我正在创建这样的 SceneWindow 实例:

SceneWindow sw = new SceneWindow(sm);

smSceneManager 对象。

但是这不起作用。我在别处读到,这是因为您无法在 javafx 构造函数中使用非零参数。

这是我收到的错误消息:

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

我该如何解决这个问题?

【问题讨论】:

  • 是的,看起来它需要一个非 arg 构造函数,所以先创建一个,然后创建一些 setter,然后再创建一些其他 init 方法?
  • 无论如何,你永远不会实例化 Application 类;你将如何使用这个构造函数?为什么不在start() 方法中创建SceneManager 实例?
  • @James_D 是当我运行SceneWindow sw = new SceneWindow(sm); 时未实例化的Application 类,因为SceneWindow 扩展了Application?在我实例化一个 SceneManager 实例之后,我在将它传递到 SceneWindow 之前与它进行交互。如果我在 start() 中实例化它,它将是空的。
  • @ErgonomicGrip 会的,但你永远不应该那样做。 Application 类在您启动应用程序时为您实例化,您应该只有一个 Application 实例。
  • 正如我在之前的评论中所说,当您调用 Application.launch(…) 时,会创建您的 Application 类的实例。所以如果你自己实例化它,你至少有两个实例。拥有一个以管理应用程序生命周期为全部目的的类的两个实例是没有意义的。

标签: java javafx


【解决方案1】:

我正在编写一个扩展 javafx 应用程序类的 java 类,并试图将一个对象传递给构造函数

不要尝试将对象传递给 JavaFX 应用程序的构造函数。

阅读JavaFX Application javadoc

Application 子类必须声明为 public,并且必须有一个 public 的无参数构造函数。

另外,研究链接的 javadoc 中的应用程序生命周期信息。

您应该在 VM 中只有一个应用程序实例,并且将由调用无参数构造函数的应用程序启动序列创建。

因此,为具有参数的应用程序创建一个额外的构造函数充其量是没有意义的,因为它永远不应该被调用。


为什么不应该手动创建新的应用程序实例

如果您的参数化构造函数是通过new 手动调用的,是的,它会创建一个新的应用程序实例。但是你会在虚拟机中有两个实例,一个由你手动创建,一个由启动器自动创建,它们会有不同的初始化状态,一个由 JavaFX 生命周期管理,一个(你手动创建的那个) ) 不会,这只会造成不必要的混乱和容易出错的情况 => 你永远不应该手动创建 JavaFX 应用程序实例。

命令行参数

注意:您可以提供具有标准 String[] args 参数列表的静态 main 方法,这些参数将通过 getParameters() 提供给应用程序实例,因此可以将参数传递给应用程序实例,但是这些参数与您尝试做的完全不同,因为它们只是命令行字符串参数,而不是任意 Java 对象引用。参数通过launch(appClass, args) 方法作为参数传递给应用程序类实例。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 2012-12-24
    • 2013-03-09
    • 1970-01-01
    • 2013-03-16
    • 2021-01-10
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多