2016-10-21 9 views
0

最後の2行はエラーを引き起こしています。コマンドスタックが空のときにボタンを無効にしたいどうしてか分かりません。例えば、削除/編集ボタンと同じボタンを無効にしても問題ありません。これらの2つのアプリケーションがなくても完全にうまく動作します。JavaFXボタンバインディング例外

例外チェーン:スタックの

javafx.fxml.LoadException: 
/home/simon/eclipse/java-neon-workspace/to2/lab2/cw3/bin/pl/edu/agh/iisg/to/javafx/cw3/view/AccountOverviewPane.fxml 

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2571) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409) 
    at pl.edu.agh.iisg.to.javafx.cw3.presenter.AccountPresenter.initRootLayout(AccountPresenter.java:35) 
    at pl.edu.agh.iisg.to.javafx.cw3.Main.start(Main.java:20) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$106(LauncherImpl.java:863) 
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$119(PlatformImpl.java:326) 
    at com.sun.javafx.application.PlatformImpl.lambda$null$117(PlatformImpl.java:295) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$118(PlatformImpl.java:294) 
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) 
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$450(GtkApplication.java:139) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) 
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566) 
    ... 13 more 
Caused by: java.lang.NullPointerException 
    at pl.edu.agh.iisg.to.javafx.cw3.view.AccountOverviewController.initialize(AccountOverviewController.java:97) 
    ... 23 more 

の両方がCommandRegistryクラス

private ObservableList<Command> commandStack = FXCollections.observableArrayList(); 

でこのように宣言されているとゲッターは自然に身を戻ってきています。おそらくここで間違っている可能性がありますか?コントローラは、クラスがCommandRegistryのインスタンスを持っている前initialize()commandRegistryにアクセスしようとするため

+0

あなたは 'AccountOverviewController'のための完全なコードを追加していただけますか?あなたのトレースに 'NullPointerException'と書かれていますが、' commandRegistry'が初期化されていますか? – beatngu13

+0

したがって、どの行が97行ですか? –

+0

この特定の例では、これは 'undoButoon.disablePrope ... 'を使って行います。しかし、それらのすべてが同じ例外チェーンを引き起こします。ここには[プロジェクト](https://github.com/Sukiennik/JavaFX-Projects/tree/master/pl/edu/agh/iisg/to/javafx/cw3)と[AccountOverviewController](http:// pastebin .com/cvGRY5z5) – Saris

答えて

1

あなたproject、特にAccountOverviewControllerAccountPresenterを見た後、私はあなたがNullPointerExceptionことを得ると思います。

AccountOverviewController controller = loader.getController(); 
controller.setPresenter(this); 
controller.setData(DataGenerator.generateAccountData()); 
controller.setCommandRegistry(commandRegistry); 

あなたのコントローラを作成し、その後commandRegistryを設定します。AccountPresenterの41 -

は、ライン38を見てください。しかし initialize()は、 AccountOverviewControllerのコンストラクタを呼び出した後に直接呼び出されます(詳細は thisの質問を参照してください)。このとき、 commandRegistrynullです。

この問題を解決する1つの方法は、セッターへのバインディングを移動することである:

public void setCommandRegistry(CommandRegistry commandRegistry) { 
    this.commandRegistry = commandRegistry; 

    undoButton.disableProperty().bind(Bindings.isEmpty(commandRegistry.getCommandStack())); 
    redoButton.disableProperty().bind(Bindings.isEmpty(commandRegistry.getUndoCommandStack())); 

    commandLogView.setItems(commandRegistry.getCommandStack()); 
    commandLogView.setCellFactory(lv -> new ListCell<Command>() { 
     protected void updateItem(Command item, boolean empty) { 
      super.updateItem(item, empty); 
      setText((item != null && !empty) ? item.getName() : null); 
     }; 
    }); 
} 
+0

ありがとう、私は今それを理解しています。どのようにしてバインディングが 'transactionsTable'上で動作するかは、呼び出し側コントローラ中でまだ初期化されていない場合です。例えば、 'editButton'や' deleteButton'です。 – Saris

+1

@Saris既にすべての依存関係が存在するためです。 'editButton'と' deleteButton'は 'transactionTable'を必要とします。これらのフィールドはすべて、前に呼び出される '@ FXML'で注釈が付けられます。あなたが覚えておかなければならないのは、この実行順序です:1.コンストラクター、2. '@ FXML'、3.' initialize() '。 – beatngu13

+0

ご協力いただきありがとうございます。 – Saris

関連する問題