javaFX:如何创建Live ListView并向其添加ChangeListener

时间:2013-07-21 08:38:16

标签: java javafx changelistener observablelist

我编写了一个JavaFX用户界面(fxml)并将控制器类绑定到它,一切正常,直到我在我的应用程序中为ListView添加了一个ObservableList和一个ChangeListener。 ListView看起来很好,并在运行应用程序时显示正确的值,但是当我单击某些按钮时,异常发生并且按钮将不起作用。这些按钮应该在单击时显示其他布局。例外情况说布局(例如AddUser.fxml)没有找到,但它存在并正常工作到现在为止!

控制器类的一些行:

public class FileSharingController implements Initializable {

private ObservableList<User> UsersListData=FXCollections.observableArrayList();
@FXML
private ListView<User> UsersList;

public FileSharingController(){
    DatabaseManager DB=new DatabaseManager();
    try {
        UsersListData.addAll(DB.returnUsers());
    } catch (SQLException e) {e.printStackTrace();}
}

@Override
public void initialize(URL location, ResourceBundle resources) {
        UsersList.setItems(UsersListData);
        UsersListData.addListener(new ListChangeListener<User>(){
            @Override
            public void onChanged(Change<? extends User> c) {
                System.out.println(c.getList());

            }
        });
}

@FXML
public void showAddUserLayout(){
    try {Stage stage=new Stage();
    AnchorPane  rootPane=FXMLLoader.load(getClass().getResource("AddUser.fxml"));
    Scene scene = new Scene(rootPane);
    stage.setScene(scene);
    stage.setTitle("Add User");
    stage.show();
} catch (IOException e) {e.printStackTrace();}
}
}

User类(Model):

package Model;

public class User {
private String Username;
private String Password;

public User(String Username,String Password){
    this.Username=Username;
    this.Password=Password;
}
public void Set(String Username,String Password){
    this.Username=Username;
    this.Password=Password;
}
public String toString(){
    return Username+"   "+Password;
}
}

当我点击“添加”按钮时,showAddUserLayout()被调用,我得到以下例外:

java.lang.NullPointerException
/D:/workspace_FileSharing%20Serverside/FileSharing_ServerSide/bin/com/Shayan/FileSharing/Server/AddUser.fxml
  at com.Shayan.FileSharing.Server.FileSharingController.updateUsersList(FileSharingController.java:144)
at com.Shayan.FileSharing.Server.FileSharingController.initialize(FileSharingController.java:50)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2152)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2028)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2742)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2721)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2694)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2683)
at com.Shayan.FileSharing.Server.FileSharingController.showAddUserLayout(FileSharingController.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1437)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3113)
at javafx.scene.Scene$ClickGenerator.access$8600(Scene.java:3051)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3333)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3164)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3119)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1559)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2261)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:228)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
      at     javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1440)
      at  com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
     at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
      at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)

请帮忙!我不知道发生了什么...... 提前谢谢!

1 个答案:

答案 0 :(得分:1)

您发布的代码不完整。 FXMLLoader正在加载“AddUser.fxml”文件。它还调用控制器的初始化方法。但nullpointerexception出现在updateUsersList()方法中的第144行。检查那条线。并且您可能希望将“AddUser.fxml”的控制器类更改为FileSharingController以外的其他控件类。

根据评论,
Does each Layout need a seperate controller?

技术上没有,但在语义上是的。如果在不同的FXML文件中设置相同的fx:controller,那么对于每个正在加载的FXML文件,最终会有该控制器的多个实例。如果您在FXMLLoader.setController()之间使用FXMLLoader.setRoot(),其中FXML文件包含fx:root而不是fx:controller,那么您最终将只有一个控制器实例{{1}将为每个正在加载的FXML文件单独调用方法。但是,在这两种情况下,每个FXML文件只在语义上处理控制器的某些部分,即初始化,注入,设置,操纵它感兴趣的部分.IMO FXML文件应该没有相互域,如果有的话必须通过自己的控制器使用普通的java消息传递机制因此,拥有另一个AddUserController类将更加模块化,可维护并且更少麻烦。