Error When Click In tableView - javafx

Why when I click in the are outside Of the row Containing data, and outside the area of column (mark as red) I get exception. This is I try using javaFX8 from oracle. I need to disable constrained policy because I need that column to take different percentage of tableview area.
package fjr.test;
/**
* Copyright (c) 2008, 2012 Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*/
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;
/**
* A simple table with a header row.
*
* #see javafx.scene.control.TableCell
* #see javafx.scene.control.TableColumn
* #see javafx.scene.control.TablePosition
* #see javafx.scene.control.TableRow
* #see javafx.scene.control.TableView
*/
public class TableSample extends Application {
private void init(Stage primaryStage) {
Group root = new Group();
primaryStage.setScene(new Scene(root));
final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith#example.com" ),
new Person("Isabella", "Johnson", "isabella.johnson#example.com" ),
new Person("Ethan", "Williams", "ethan.williams#example.com" ),
new Person("Emma", "Jones", "emma.jones#example.com" ),
new Person("Michael", "Brown", "michael.brown#example.com" )
);
TableColumn firstNameCol = new TableColumn();
firstNameCol.setText("First");
firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
TableColumn lastNameCol = new TableColumn();
lastNameCol.setText("Last");
lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
TableColumn emailCol = new TableColumn();
emailCol.setText("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(new PropertyValueFactory("email"));
TableView tableView = new TableView();
tableView.setItems(data);
tableView.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
root.getChildren().add(tableView);
}
public static class Person {
private StringProperty firstName;
private StringProperty lastName;
private StringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public StringProperty firstNameProperty() { return firstName; }
public StringProperty lastNameProperty() { return lastName; }
public StringProperty emailProperty() { return email; }
}
#Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}
The stacktrace:
run:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.handleSelectedCellsListChangeEvent(TableView.java:2657)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2180)
at javafx.scene.control.TableView$TableViewArrayListSelectionModel.clearAndSelect(TableView.java:2140)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.doSelect(TableRowBehavior.java:196)
at com.sun.javafx.scene.control.behavior.TableRowBehavior.mousePressed(TableRowBehavior.java:88)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:204)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3746)
at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3471)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1695)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2486)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
at com.sun.glass.ui.View.notifyMouse(View.java:898)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
BUILD SUCCESSFUL (total time: 5 seconds)

Related

Tableview doesn't show content?

I'm trying to show some data on tableview that (e.g first name ,last name ,email etc)
I used the code from oracle documentation is like that :
import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.geometry.Insets; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.stage.Stage; public class TableViewSample extends Application { private TableView<Person> table = new TableView<Person>(); private final ObservableList<Person> data = FXCollections.observableArrayList( new Person("Jacob", "Smith", "jacob.smith#example.com"), new Person("Isabella", "Johnson", "isabella.johnson#example.com"), new Person("Ethan", "Williams", "ethan.williams#example.com"), new Person("Emma", "Jones", "emma.jones#example.com"), new Person("Michael", "Brown", "michael.brown#example.com") ); public static void main(String[] args) { launch(args); } #Override public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("Table View Sample"); stage.setWidth(450); stage.setHeight(500); final Label label = new Label("Address Book"); label.setFont(new Font("Arial", 20)); table.setEditable(true); TableColumn firstNameCol = new TableColumn("First Name"); firstNameCol.setMinWidth(100); firstNameCol.setCellValueFactory( new PropertyValueFactory<Person, String>("firstName")); TableColumn lastNameCol = new TableColumn("Last Name"); lastNameCol.setMinWidth(100); lastNameCol.setCellValueFactory( new PropertyValueFactory<Person, String>("lastName")); TableColumn emailCol = new TableColumn("Email"); emailCol.setMinWidth(200); emailCol.setCellValueFactory( new PropertyValueFactory<Person, String>("email")); table.setItems(data); table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); final VBox vbox = new VBox(); vbox.setSpacing(5); vbox.setPadding(new Insets(10, 0, 0, 10)); vbox.getChildren().addAll(label, table); ((Group) scene.getRoot()).getChildren().addAll(vbox); stage.setScene(scene); stage.show(); } public static class Person { private final SimpleStringProperty firstName; private final SimpleStringProperty lastName; private final SimpleStringProperty email; private Person(String fName, String lName, String email) { this.firstName = new SimpleStringProperty(fName); this.lastName = new SimpleStringProperty(lName); this.email = new SimpleStringProperty(email); } public String getFirstName() { return firstName.get(); } public void setFirstName(String fName) { firstName.set(fName); } public String getLastName() { return lastName.get(); } public void setLastName(String fName) { lastName.set(fName); } public String getEmail() { return email.get(); } public void setEmail(String fName) { email.set(fName); } } }
I got exception :
Feb 13, 2022 8:21:24 PM javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively
WARNING: Can not retrieve property 'firstName' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory#67bfcda1 with provided class type: class application.TableViewSample$Person
java.lang.RuntimeException: java.lang.IllegalAccessException: module javafx.base cannot access class application.TableViewSample$Person (in module myTabel) because module myTabel does not open application to javafx.base
Add the line:
opens application to javafx.base
to your module-info.Java file.
Study and learn how Java 9 modules work.
Searching for the error message will tell you about it and how to fix it.
Search also for lambda vs PropertyValueFactory. Using lambdas is an alternate way to address your issues.

Adding a CheckBox column to an existing TableView

I recently wanted to add a CheckBox column to an existing TableView. To study the problem in isolation, I started with Example 13-6 Creating a Table and Adding Data to It. I added a BooleanProperty and accessors to the Person model class, and I added a new TableColumn with a CheckBoxTableCell as the cell factory. As shown in the image, I see a CheckBox on each row. Although all values are true, none are checked; the checkboxes are live, but setActive() is never called. Recent questions on this topic suggest that I'm missing something; I'd welcome any insight.
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
/**
* Example 13-6 Creating a Table and Adding Data to It
* https://docs.oracle.com/javase/8/javafx/user-interface-tutorial/table-view.htm#CJAGAAEE
*/
public class TableViewSample extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data
= FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith#example.com"),
new Person("Isabella", "Johnson", "isabella.johnson#example.com"),
new Person("Ethan", "Williams", "ethan.williams#example.com"),
new Person("Emma", "Jones", "emma.jones#example.com"),
new Person("Michael", "Brown", "michael.brown#example.com")
);
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Table View Sample");
stage.setWidth(600);
stage.setHeight(400);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn<Person, Boolean> active = new TableColumn<>("Active");
active.setCellValueFactory(new PropertyValueFactory<>("active"));
active.setCellFactory(CheckBoxTableCell.forTableColumn(active));
TableColumn<Person, String> firstName = new TableColumn<>("First Name");
firstName.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person, String> lastName = new TableColumn<>("Last Name");
lastName.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<Person, String> email = new TableColumn<>("Email");
email.setCellValueFactory(new PropertyValueFactory<>("email"));
table.setItems(data);
table.getColumns().addAll(active, firstName, lastName, email);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(8));
vbox.getChildren().addAll(label, table);
stage.setScene(new Scene(vbox));
stage.show();
}
public static class Person {
private final BooleanProperty active;
private final StringProperty firstName;
private final StringProperty lastName;
private final StringProperty email;
private Person(String fName, String lName, String email) {
this.active = new SimpleBooleanProperty(true);
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public boolean getActive() {
return active.get();
}
public void setActive(boolean b) {
active.set(b);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String s) {
firstName.set(s);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String s) {
lastName.set(s);
}
public String getEmail() {
return email.get();
}
public void setEmail(String s) {
email.set(s);
}
}
}
Summary: As noted here, this is likely a bug; steps to avoid the pitfall include these:
Verify that the data model exports properties correctly, as shown here.
Critically examine the value of replacing PropertyValueFactory with an explicit Callback, when possible, as outlined here, here, here, here and here.
The problem is that CheckBoxTableCell can't find or bind the ObservableProperty<Boolean> based on the parameter supplied:
active.setCellFactory(CheckBoxTableCell.forTableColumn(active));
The CheckBoxTableCell defers to the table column for access to the target Boolean property. To see the effect, replace the active parameter with a Callback that returns the ObservableValue<Boolean> for row i explicitly:
active.setCellFactory(CheckBoxTableCell.forTableColumn(
(Integer i) -> data.get(i).active));
While this makes the checkboxes work, the underlying problem is that the Person class needs an accessor for the active property. Using JavaFX Properties and Binding discusses the property method naming conventions, and the Person class of the Ensemble8 tablecellfactory illustrates a working model class with a property getter for each attribute, also shown below.
With this change PropertyValueFactory can find the newly added BooleanProperty, and the original form of forTableColumn() works. Note that the convenience of PropertyValueFactory comes with some limitations. In particular, the factory's fall-through support for the previously missing property accessor goes unnoticed. Fortunately, the same accessor allows substitution of a simple Callback for each column's value factory. As shown here, instead of PropertyValueFactory,
active.setCellValueFactory(new PropertyValueFactory<>("active"));
Pass a lamda expression that returns the corresponding property:
active.setCellValueFactory(cd -> cd.getValue().activeProperty());
Note also that Person can now be private. Moreover, the use of explicit type parameters affords stronger type checking during compilation.
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
/**
* https://stackoverflow.com/a/68969223/230513
*/
public class TableViewSample extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data
= FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith#example.com"),
new Person("Isabella", "Johnson", "isabella.johnson#example.com"),
new Person("Ethan", "Williams", "ethan.williams#example.com"),
new Person("Emma", "Jones", "emma.jones#example.com"),
new Person("Michael", "Brown", "michael.brown#example.com")
);
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Table View Sample");
stage.setWidth(600);
stage.setHeight(400);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn<Person, Boolean> active = new TableColumn<>("Active");
active.setCellValueFactory(cd -> cd.getValue().activeProperty());
active.setCellFactory(CheckBoxTableCell.forTableColumn(active));
TableColumn<Person, String> firstName = new TableColumn<>("First Name");
firstName.setCellValueFactory(cd -> cd.getValue().firstNameProperty());
TableColumn<Person, String> lastName = new TableColumn<>("Last Name");
lastName.setCellValueFactory(cd -> cd.getValue().lastNameProperty());
TableColumn<Person, String> email = new TableColumn<>("Email");
email.setCellValueFactory(cd -> cd.getValue().emailProperty());
table.setItems(data);
table.getColumns().addAll(active, firstName, lastName, email);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(8));
vbox.getChildren().addAll(label, table);
stage.setScene(new Scene(vbox));
stage.show();
}
private static class Person {
private final BooleanProperty active;
private final StringProperty firstName;
private final StringProperty lastName;
private final StringProperty email;
private Person(String fName, String lName, String email) {
this.active = new SimpleBooleanProperty(true);
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public BooleanProperty activeProperty() {
return active;
}
public StringProperty firstNameProperty() {
return firstName;
}
public StringProperty lastNameProperty() {
return lastName;
}
public StringProperty emailProperty() {
return email;
}
}
}

Javafx Binding throw exception in application start() method

UnsupportedOperationException thrown in Bindings.bindContent() when bind the objects to TableView. Why? How to resolve this problem?
I am using java 8 update181.
Exception in Application start method 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 com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
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.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at java.util.AbstractList.removeRange(AbstractList.java:571)
at java.util.AbstractList.clear(AbstractList.java:234)
at com.sun.javafx.binding.ContentBinding.bind(ContentBinding.java:55)
at javafx.beans.binding.Bindings.bindContent(Bindings.java:1020)
at problem_bind.Main.start(Main.java:42)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
... 1 more Exception running application problem_bind.Main
My codes:
package problem_bind;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
House house = new House();
TableView<Person> table = new TableView<>();
table.setEditable(true);
TableColumn<Person, String> firstNameColumn = createColumn("First Name", "firstName");
TableColumn<Person, String> lastNameColumn = createColumn("Last Name", "lastName");
table.getColumns().add(firstNameColumn);
table.getColumns().add(lastNameColumn);
ObservableList<Person> data = FXCollections.observableArrayList();
data.addAll(house.getPersons());
table.setItems(data);
Bindings.bindContent(house.getPersons(), table.getItems());
BorderPane root = new BorderPane(table, null, null, null, null);
root.setPadding(new Insets(10));
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
private TableColumn<Person, String> createColumn(String title, String property) {
TableColumn<Person, String> col = new TableColumn<>(title);
col.setSortable(false);
col.setCellValueFactory(
new PropertyValueFactory<Person, String>(property));
col.setCellFactory(TextFieldTableCell.forTableColumn());
return col ;
}
public static class House {
private List<Person> persons = new ArrayList<Person>();
public House() {
this.persons = Arrays.asList(
new Person("Jacob", "Smith", this),
new Person("Isabella", "Johnson", this),
new Person("Ethan", "Williams", this),
new Person("Emma", "Jones", this),
new Person("Michael", "Brown", this));
}
public List<Person> getPersons() {
return persons;
}
}
public static class Person {
private String firstName ;
private String lastName ;
private House house;
public Person(String firstName, String lastName, House house) {
this.firstName = firstName ;
this.lastName = lastName ;
this.house = house;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
}
The problem is your use of Arrays.asList(Object...). That method:
Returns a fixed-size list backed by the specified array.
Because of this, the returned List does not support operations such as add or remove. Instead, you'd modify such a list through the set method. The former two methods inherently require a variable-sized list. The implementation of Bindings.bindContent apparently tries to use those unsupported methods when synchronizing the lists.
Change this:
this.persons = Arrays.asList(
new Person("Jacob", "Smith", this),
new Person("Isabella", "Johnson", this),
new Person("Ethan", "Williams", this),
new Person("Emma", "Jones", this),
new Person("Michael", "Brown", this));
To this:
persons = new ArrayList<>();
persons.add(new Person("Jacob", "Smith", this));
persons.add(new Person("Isabella", "Johnson", this));
persons.add(new Person("Ethan", "Williams", this));
persons.add(new Person("Emma", "Jones", this));
persons.add(new Person("Michael", "Brown", this));
Note: In your current code, prefixing with this is unnecessary. But you can still use it if you prefer.
Note #2: See #Pagbo's comment.
Basically, make sure you use a List which supports the add and remove operations.
You may be wondering why calling Bindings.bindContent(List,ObservableList) is leading to a remove call in the first place. This is because that method returns:
A content binding [ensuring] that the List contains the same elements as the ObservableList. If the content of the ObservableList changes, the List will be updated automatically.
In other words, the List is updated to match the ObservableList. This involves, when first creating the binding, clearing the List then adding all the elements of the ObservableList to it.

JavaFX FileChooser throws NullPointerException when called

I am having a problem opening a FileChooser in JavaFX as it throws an error when i call showOpenDialog(...) method, i searched for similar threads like the link i posted below but couldn't make it work.
The error is thrown when i call the addHtml() method on EmailSenderController to add the html file text to the html editor.
Similar thread but with the exception that i didn't initialize the #FXML injected controls like he did : JavaFX FileChooser Throws Error (probably easy fix, but still confused)
Main class
package emailsender;
import configuration.ProjectConfiguration;
import emailsender.controllers.EmailSenderController;
import emailsender.services.FileReaderService;
import emailsender.services.ViewLoaderService;
import java.io.IOException;
import javafx.application.Application;
import javafx.stage.Stage;
/**
*
* #author DJava
*/
public class EmailSender extends Application {
#Override
public void start(Stage primaryStage) throws IOException, Exception
{
//Main configuration
ProjectConfiguration configuration = new
ProjectConfiguration();
configuration.setStage(primaryStage);
configuration.setViewsPath("emailsender/views/");
//Services
ViewLoaderService viewloaderService = new
ViewLoaderService(configuration);
FileReaderService fileReaderService = new
FileReaderService(configuration);
//Controllers
EmailSenderController sender = new
EmailSenderController(viewloaderService, fileReaderService);
sender.start(configuration.getStage());
}
public static void main(String[] args) {
launch(args);
}
}
View Loader Service
package emailsender.services;
import configuration.ProjectConfiguration;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
/**
*
* #DJava
*/
public class ViewLoaderService {
ProjectConfiguration configuration;
public ViewLoaderService(ProjectConfiguration configuration) {
this.configuration = configuration;
}
public Scene loadViewOnScene(String view) throws IOException {
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource(this.configuration.getViewsPath() + view + ".fxml"));
return new Scene(root);
}
}
Controller
package emailsender.controllers;
import emailsender.services.FileReaderService;
import javafx.application.Application;
import javafx.stage.Stage;
import emailsender.services.ViewLoaderService;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
/**
*
* #author DJava
*/
public class EmailSenderController extends Application {
private ViewLoaderService viewLoaderService;
private FileReaderService fileReaderService;
private WebEngine webEngine;
//Header
//EmaiLSender menu
#FXML
public MenuItem newListMenuItem;
#FXML
public MenuItem preferencesMenuItem;
#FXML
public MenuItem closeMenuItem;
//Help menu
#FXML
public MenuItem aboutMenuItem;
//Email tab
#FXML
public TextField subjectTextField;
#FXML
public ComboBox destinationListComboBox;
#FXML
public Button addHtmlButton;
#FXML
public HTMLEditor messageEditor;
#FXML
public ProgressIndicator sendTaskProgressIndicator;
//Preview tab
#FXML
public WebView previewWebView;
//Footer
#FXML
public Button sendButton;
public EmailSenderController() {
}
public EmailSenderController(ViewLoaderService viewLoaderService,
FileReaderService fileReaderService) {
this.viewLoaderService = viewLoaderService;
this.fileReaderService = fileReaderService;
}
#FXML
public void addHtml() {
this.messageEditor.setHtmlText
(this.fileReaderService.getFileText()); // Here is the problem ..........
}
#FXML
public void previewEmail() {
this.webEngine = this.previewWebView.getEngine();
this.webEngine.loadContent(this.messageEditor.getHtmlText());
}
#FXML
public void sendEmail() {
this.sendTaskProgressIndicator.setProgress(0.3D);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("EmailSender");
primaryStage.setScene(viewLoaderService.loadViewOnScene("EmailSender"));
primaryStage.setResizable(false);
primaryStage.show();
}
}
File Reader Service
package emailsender.services;
import configuration.ProjectConfiguration;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import javafx.stage.FileChooser;
/**
*
* #author DJava
*/
public class FileReaderService {
private final ProjectConfiguration configuration;
private final FileChooser fileChooser;
public FileReaderService(ProjectConfiguration configuration) {
this.configuration = configuration;
this.fileChooser = new FileChooser();
}
public String getFileText() {
String text = "";
try {
BufferedReader reader = new BufferedReader(new FileReader(this.fileChooser.showOpenDialog(this.configuration.getStage())));
String line;
while ((line = reader.readLine()) != null) {
text += line + "\n";
}
} catch (IOException event) {
event.printStackTrace();
}
System.out.println(text);
return text;
}
}
Error
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
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$MethodHandler.invoke(FXMLLoader.java:1771)
... 49 more
Caused by: java.lang.NullPointerException
at emailsender.controllers.EmailSenderController.addHtml(EmailSenderController.java:77)
... 59 more
The problem is the controller that executes the addHtml method and the one you initially create is not the same. When you load the EmailSender, the FXMLLoader uses the empty constructor to create a new controller. Hence the constructor which sets the attributes is not called and you end up with null attributes.
To get the correct controller, use the loader's getController method and set the attributes with appropriate set methods:
FXMLLoader loader = new FXMLLoader("fxml file") ;
loader.load();
EmailSenderController controller = (EmailSenderController) loader .getController() ;
controller.setFileReadService(frs) ; // frs created elsewhere
On another note, your class architecture is a bit weird. You should only have one Application class. A controller should never be an application class. Its job is to control a view, not to run an entire window. As a suggestion, change your configuration to load the views and controllers as shown above. The controller attributes must be set right after loading the views.
Then in your EmailSender start method, simply load the view you want to be shown first before the end of the method.
EDIT
The reason your ViewLoaderService currently works is the way you set up your program, and illustrates why a controller shouldn't be an application. You create an instance of the controller with attributes. Then you instruct the controller to load the view (coincidentally the very view it represents). On the load of the view a new instance of the controller is created with its empty constructor (hence the null values). This new controller then acts as the controller for the displayed view, not the one you created at the start of the application.

Not allowing me to do each action more than once

I am having an issue with my code where whenever I try to do something more than once, the program will crash on me. For example, if I login, then log out and then log back in for a second time, the program will crash. This is happening for other things that I want to do more than once such as switching to another scene, going back to home then trying to go to the other scene again.
Will just post the code for the login part.
Main
package libraryapp;
import java.io.File;
import java.io.IOException;
import java.util.prefs.Preferences;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import libraryapp.model.Book;
import libraryapp.model.BookListWrapper;
import libraryapp.view.BrowseController;
import libraryapp.view.HomeOverviewController;
import libraryapp.view.LoginController;
import libraryapp.view.RootLayoutController;
public class LibraryApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
/**
* The data as an observable list of Books.
*/
private ObservableList<Book> bookData = FXCollections.observableArrayList();
/**
* Constructor
*/
public LibraryApp() {
// Add some sample data
bookData.add(new Book("Hans", "Muster"));
bookData.add(new Book("Ruth", "Mueller"));
bookData.add(new Book("Heinz", "Kurz"));
bookData.add(new Book("Cornelia", "Meier"));
bookData.add(new Book("Werner", "Meyer"));
bookData.add(new Book("Lydia", "Kunz"));
bookData.add(new Book("Anna", "Best"));
bookData.add(new Book("Stefan", "Meier"));
bookData.add(new Book("Martin", "Mueller"));
}
/**
* Returns the data as an observable list of Books.
* #return
*/
public ObservableList<Book> getBookData() {
return bookData;
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("LibraryApp");
initRootLayout();
showLogin();
}
/**
* Initializes the root layout and tries to load the last opened
* person file.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(LibraryApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
// Give the controller access to the main app.
RootLayoutController controller = loader.getController();
controller.setLibraryApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
// Try to load last opened person file.
File file = getBookFilePath();
if (file != null) {
loadBookDataFromFile(file);
}
}
/**
* Shows the home overview inside the root layout.
*/
public void showHomeOverview() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(LibraryApp.class.getResource("view/HomeOverview.fxml"));
AnchorPane homeOverview = (AnchorPane) loader.load();
// Set home overview into the center of root layout.
rootLayout.setCenter(homeOverview);
// Give the controller access to the main app.
HomeOverviewController controller = loader.getController();
controller.setLibraryApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
public void showLogin() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(LibraryApp.class.getResource("view/Login.fxml"));
AnchorPane login = (AnchorPane) loader.load();
// Set home overview into the center of root layout.
rootLayout.setCenter(login);
// Give the controller access to the main app.
LoginController controller = loader.getController();
controller.setLibraryApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
public void showBrowse() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(LibraryApp.class.getResource("view/Browse.fxml"));
AnchorPane browse = (AnchorPane) loader.load();
// Set browse into the center of root layout.
rootLayout.setCenter(browse);
// Give the controller access to the main app.
BrowseController controller = loader.getController();
controller.setLibraryApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the main stage.
* #return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
Application.launch(args);
}
Login Controller
package libraryapp.view;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import libraryapp.LibraryApp;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* FXML Controller class
*
* #author Michael
*/
public class LoginController implements Initializable {
/**
* Initializes the controller class.
*/
#FXML
private AnchorPane loginPane;
#FXML
private Label lblMessage;
#FXML
private TextField txtUsername;
#FXML
private PasswordField txtPassword;
private LibraryApp libraryApp;
public String getString(String tagName) throws SAXException, IOException, ParserConfigurationException{
File file = new File("src/libraryapp/account.xml");
DocumentBuilderFactory docBuildFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuildFactory.newDocumentBuilder();
Document document = docBuilder.parse(file);
NodeList list = document.getElementsByTagName(tagName);
if (list != null && list.getLength() > 0){
NodeList subList = list.item(0).getChildNodes();
if (subList != null && subList.getLength() > 0) {
return subList.item(0).getNodeValue();
}
}
return null;
}
#FXML
private void login(ActionEvent event) throws IOException, ParserConfigurationException, SAXException {
String email = getString("email");
String password = getString("password");
if (txtUsername.getText().equals(email) && txtPassword.getText().equals(password)){
libraryApp.showHomeOverview();
} else{
lblMessage.setText("Username or password invalid!");
}
}
#FXML
private void register(ActionEvent event) throws IOException {
AnchorPane pane = FXMLLoader.load(getClass().getResource("Register.fxml"));
loginPane.getChildren().setAll(pane);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLibraryApp(LibraryApp libraryApp) {
this.libraryApp = libraryApp;
}
}
And this is the error that I get
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
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$MethodHandler.invoke(FXMLLoader.java:1769)
... 52 more
Caused by: java.lang.NullPointerException
at libraryapp.view.LoginController.login(LoginController.java:82)
... 62 more
Logout
#FXML
public void logout(ActionEvent event) throws IOException {
File bookFile = libraryApp.getBookFilePath();
libraryApp.saveBookDataToFile(bookFile);
AnchorPane pane = FXMLLoader.load(getClass().getResource("Login.fxml"));
browsePane.getChildren().setAll(pane);
}
Your implementation of logout() loads the login fxml file again, but does not set the libraryApp field on the new controller. Consequently, that field is null in that instance of the controller, and you get a null pointer exception.
Since you already have a reference to the libraryApp, you can reuse the existing code to load the login screen simply by calling
libraryApp.showLogin();

Resources