2016-10-21 2 views
0
public class AccountOverviewController { 

//declarations ... 

@FXML 
private Button undoButton; 

@FXML 
private Button redoButton; 

@FXML 
private void initialize() { 
    transactionsTable.getSelectionModel().setSelectionMode(
      SelectionMode.MULTIPLE); 

    dateColumn.setCellValueFactory(dataValue -> dataValue.getValue() 
      .getDateProperty()); 
    payeeColumn.setCellValueFactory(dataValue -> dataValue.getValue() 
      .getPayeeProperty()); 
    categoryColumn.setCellValueFactory(dataValue -> dataValue.getValue() 
      .getCategoryProperty()); 
    inflowColumn.setCellValueFactory(dataValue -> dataValue.getValue() 
      .getInflowProperty()); 

    deleteButton.disableProperty().bind(Bindings.isEmpty(transactionsTable.getSelectionModel().getSelectedItems())); 

    editButton.disableProperty().bind(Bindings.size(transactionsTable.getSelectionModel().getSelectedItems()).isNotEqualTo(1)); 

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

//handlers&setters ... 
} 

Diese zwei Zeilen am Ende verursachen einen Fehler. Ich möchte Tasten deaktivieren, wenn die Stapel der Befehle leer sind. Ich weiß nicht warum. Zum Beispiel funktioniert die gleiche Schaltfläche zum Deaktivieren/Bearbeiten der Schaltfläche einwandfrei. Ganze Anwendung ohne diese beiden funktioniert vollkommen in Ordnung.Ausnahme für JavaFX-Schaltflächenbindung

Ausnahme Kette:

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 

Beide Stapel werden wie folgt erklärt in CommandRegistry Klasse

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

und Getter kehren sich natürlich. Was könnte hier schief gehen?

+0

Könnten Sie bitte den vollständigen Code für 'AccountOverviewController' hinzufügen? Ihr Trace sagt 'NullPointerException', sind Sie sicher, dass' commandRegistry' initialisiert ist? – beatngu13

+0

Also welche Linie ist Linie 97? –

+0

In diesem speziellen Beispiel ist es das mit 'undoButoon.disablePrope ...'. Aber jeder von ihnen verursacht dieselbe Ausnahmekette. Hier ist das ganze [Projekt] (https://github.com/Sukiennik/JavaFX-Projects/tree/master/pl/edu/agh/iisg/to/javafx/cw3) und hier [AccountOverviewController] (http: // pastebin .com/cvGRY5z5) – Saris

Antwort

1

Nachdem bei Ihrer project suchen, vor allem AccountOverviewController und AccountPresenter, würde ich sagen, dass NullPointerException bekommen, weil der Controller commandRegistry innerhalb initialize()vor die Klasse eine Instanz von CommandRegistry hat zuzugreifen versucht.

Werfen Sie einen Blick in den Zeilen 38 bis 41 von AccountPresenter:

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

Sie Ihren Controller erstellen und commandRegistry danach. Aber initialize() wird direkt nach dem Aufruf des Konstruktors von AccountOverviewController aufgerufen (Check-out this Frage für Details). Zu dieser Zeit ist commandRegistrynull.

Eine Möglichkeit, dies zu beheben, ist durch die Bindungen in den Setter bewegt:

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

Danke, ich verstehe es jetzt. Wie funktionieren Bindings dann auf transactionsTable, wenn sie auch beim Aufruf des Controllers noch nicht initialisiert wurde? Zum Beispiel 'editButton' oder' deleteButton'. – Saris

+1

@Saris Da alle Abhängigkeiten bereits da sind. 'editButton' und' deleteButton' benötigen 'transactionTable'. Alle diese Felder sind mit '@ FXML' versehen, das zuvor aufgerufen wurde. Alles, was Sie sich merken müssen, ist diese Ausführungsreihenfolge: 1. Konstruktor, 2. '@ FXML', 3.' initialize() '. – beatngu13

+0

Vielen Dank für Ihre Hilfe und Geduld. – Saris