2

私は現在 Java FX プロジェクトに取り組んでおり、複数の FXML に対して 1 つのコントローラーを使用しています (理由は聞かないでください)。私が直面している問題は、すべての新しい FXML 呼び出しで、コントローラーが新しいオブジェクトを作成することです。ずっと同じコントローラーで作業したいので、コントローラーのコンストラクターをシングルトンとして実装しようとしました

public Controller(){}
private static Controller controller = null;

public synchronized static Controller getInstance() {
    if (controller == null)
        controller = new Controller();
    return controller;
}

この戦略では、FXML ごとに新しいコンストラクターを作成しないと Java FX が機能しないように見えるため、次のエラーが発生します。他に可能なアプローチはありますか?

これは私が直面しているエラーです: /Users/dwome/git/4winner/4win/target/classes/win/javafxscene.fxml:11

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:934)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at win.Main.start(Main.java:24)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.ReflectUtil can not access a member of class win.Controller with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
... 19 more

アプリケーション win.Main の実行中に例外が発生しました

4

2 に答える 2

2

質問が古いことは知っていますが、コメントしていないのでうまくいきました。この質問はよく見られているようです。同じ問題に直面したときに私がしたことを言います。

私は彼の答えでダース忍者が言ったことを使用しました.

私のエラーはまったく同じではありませんでしたが、とにかくうまくいくと思います。複数のFXMLに対して1つのコントローラーがありました。

私の手順は次のとおりです。

  1. fx:controller="path.to.controller"各FXMLから削除
  2. 関数を作成しましたloadFXML

    private void loadFXML(String pathToFile){
        try{
            InputStream fxmlStream = getInstance().getClass().getResourceAsStream(path);
            FXMLLoader loader = new FXMLLoader();
            loader.setBuilderFactory(new JavaFXBuilderFactory());
            loader.setLocation(getInstance().getClass().getResource(path));
            loader.setController(instance);
            BorderPane panee = (BorderPane) loader.load(fxmlStream);
            Scene scene = new Scene(pane);
        }
    }
    

ご覧のとおり、私はやっていますgetInstance()loader.setController(instance);

  1. インスタンスinstance化...「ラチェット」方式で行いました

    private static Controller instance;
    static{
         if (instance == null)}
              instance = new Controller();
         }
    }
    

6 か月前なので、あなたのケースは役に立たないかもしれませんが、他の人には役立つかもしれません!

于 2016-05-06T14:00:42.437 に答える
1

FXMLLoader を使用して fxml をロードします。setController()を介してコントローラーの注入を呼び出すことができます。

または、 fxml をロードするときにController Factoryを使用します。コントローラーファクトリーは同じコントローラーオブジェクトを返すことができます

于 2015-10-22T01:11:18.677 に答える