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 ... 
} 

마지막 두 줄은 오류의 원인입니다. 명령 스택이 비어있을 때 버튼을 비활성화하고 싶습니다. 나는 이유를 모른다. 예를 들어 Delete/Edit 버튼에 대해 동일한 버튼 비활성화가 잘 작동합니다. 이 두 가지가없는 전체 응용 프로그램은 완벽하게 작동합니다.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입니다.

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