У меня есть ArrayList в моем UserController, в котором хранятся все мои экземпляры User.
Я могу использовать свой setUserList для успешной установки ArrayList, поскольку я могу прокручивать и печатать имя пользователя с помощью currentUser.getFirstName()
Я запускаю функцию входа в систему с помощью кнопки JavaFX и получаю исключение NullPointer, когда просто пытаюсь напечатать размер ArrayList, который ранее имел размер 1, и печатал имя пользователя.
Пользовательский контроллер:
public class UserController {
public ArrayList<User> userList; //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
public void setUserList(ArrayList list){
userList = list;
for (User user : userList) {
User currentUser = (User) user;
String firstName = currentUser.getFirstName();
System.out.println("Users in the UserController: " + firstName); //prints the user thomas
}
}
public void login(){
try {
System.out.println(userList.size()); //null pointer
} catch (Exception e) {
System.out.println(e);
}
}
}
UserInterface, содержащий метод входа в систему
public class UserInterface extends Application {
User loggedInUser;
UserRepo userRepo = new UserRepo();
UserController userController = new UserController();
Connection conn;
//login.fxml
@FXML
public TextField InputEmailAddress;
@FXML
public TextField InputPassword;
@Override
public void start(Stage stage) throws Exception {
String connectionURL = "jdbc:derby://localhost:1527/gymManager";
String userName = "root";
String userPassword= "root";
try {
conn = DriverManager.getConnection(connectionURL, userName, userPassword);
if (conn != null){
System.out.println("Connected to the database");
ArrayList<User> list = userRepo.read(conn);
userController.setUserList(list); //here is where I set the ArrayList<Users> in the USerController
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
} catch(SQLException e){
System.out.println("Exception:" + e.toString());
}
}
public static void main(String[] args) {
launch(args);
}
public void login(ActionEvent event) throws Exception{
userController.login();
}
}
логин.fxml
<?xml version = "1.0" encoding = "UTF-8"?>
<?import java.lang.String?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<Pane maxHeight = "-Infinity" maxWidth = "-Infinity" minHeight = "-Infinity" minWidth = "-Infinity" prefHeight = "720.0" prefWidth = "1080.0" styleClass = "main-pane" xmlns:fx = "http://javafx.com/fxml/1" fx:controller = "classmanager.UserInterface">
<children>
<Button fx:id = "loginButton" layoutX = "583.0" layoutY = "451.0" onAction = "#login" mnemonicParsing = "false" prefHeight = "56.0" prefWidth = "191.0" text = "Log In">
<font>
<Font name = "Montserrat Regular" size = "13.0" />
</font>
<styleClass>
<String fx:value = "white-btn" />
<String fx:value = "bg-blue" />
<String fx:value = "rounded-btn" />
</styleClass></Button>
<Button layoutX = "784.0" layoutY = "451.0" mnemonicParsing = "false" prefHeight = "56.0" prefWidth = "158.0" text = "I'm new here">
<font>
<Font name = "Montserrat Regular" size = "13.0" />
</font>
<styleClass>
<String fx:value = "outline-btn" />
<String fx:value = "rounded-btn" />
</styleClass></Button>
<Button layoutX = "563.0" layoutY = "514.0" mnemonicParsing = "false" prefHeight = "38.0" prefWidth = "231.0" styleClass = "transparent-btn" text = "I've forgotten my password">
<font>
<Font name = "Montserrat Regular" size = "13.0" />
</font></Button>
<Label layoutX = "581.0" layoutY = "273.0" prefHeight = "18.0" prefWidth = "411.0" text = "Book classes and manage your membership details here" textFill = "#9a9a9a">
<font>
<Font name = "Montserrat Regular" size = "14.0" />
</font>
</Label>
<Label layoutX = "577.0" layoutY = "180.0" prefHeight = "18.0" prefWidth = "353.0" text = "Welcome to the" textFill = "#1a73b5">
<font>
<Font name = "Montserrat Medium" size = "30.0" />
</font>
</Label>
<Label layoutX = "577.0" layoutY = "217.0" prefHeight = "50.0" prefWidth = "411.0" text = "Village Hotel Gym" textFill = "#1a73b5">
<font>
<Font name = "Montserrat Medium" size = "40.0" />
</font>
</Label>
<ImageView fitHeight = "730.0" fitWidth = "544.0" layoutX = "-25.0" layoutY = "-4.0" pickOnBounds = "true" preserveRatio = "true">
<image>
<Image url = "@../login-banner.jpg" />
</image>
</ImageView>
<TextField fx:id = "InputEmailAddress" layoutX = "581.0" layoutY = "325.0" prefHeight = "50.0" prefWidth = "386.0" promptText = "Email address" styleClass = "login-input">
<opaqueInsets>
<Insets left = "20.0" />
</opaqueInsets>
<font>
<Font name = "Montserrat Regular" size = "13.0" />
</font>
</TextField>
<TextField fx:id = "InputPassword" layoutX = "581.0" layoutY = "384.0" prefHeight = "50.0" prefWidth = "386.0" promptText = "Password" styleClass = "login-input">
<opaqueInsets>
<Insets left = "20.0" />
</opaqueInsets>
<font>
<Font name = "Montserrat Regular" size = "13.0" />
</font>
</TextField>
</children>
</Pane>
Я просто не могу понять, почему один метод (setUserList) в классе UserController скажет мне, что ArrayList содержит 1 пользователя, а другой (логин) вернет NullPointer
Спасибо за любые советы
Вероятно, вы вызываете setUserList в одном экземпляре UserController, а затем вызываете login в другом экземпляре. Из вашего кода неясно, откуда берется значение userController и какой экземпляр UserController метода login вызывается.
так что одна копия может быть разделена между различными функциями
Согласен с @MikhailVladimirov. Или вы вызываете login() для того же экземпляра перед вызовом setUserList.
Привет, спасибо, что так быстро вернулись. Я обновил вопрос, чтобы показать полный класс UserInterface. Из того, что я вижу, и setUserList, и логин вызываются в одном и том же экземпляре userController.
Кажется, у вас есть два экземпляра UserController. Тот, который вы создаете в UserInterface и устанавливаете для него список пользователей. Второй создается для login.fxml и вызывается при действии. Не могли бы вы предоставить свой логин.fxml?
Метод read в UserRepo не включен, поэтому мы не знаем, что там происходит. Лично мне не нравится устанавливать методы для объектов коллекции, я предпочитаю иметь что-то вроде addUsers(List newUsers), где я делаю addAll(newUsers) внутри метода, а затем переменная списка в классе всегда инициализируется в конструкторе
Я добавил файл login.fxml :)
@TomBudge смотрите мой ответ ниже.




Пожалуйста, измените свой пользовательский контроллер следующим образом и посмотрите, работает ли он:
public class UserController {
public ArrayList<User> userList = new ArrayList<>(); //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
public void setUserList(ArrayList list){
userList.addAll(list);
for (User user : userList) {
User currentUser = (User) user;
String firstName = currentUser.getFirstName();
System.out.println("Users in the UserController: " + firstName); //prints the user thomas
}
}
public void login(){
try {
System.out.println(userList.size()); //null pointer
} catch (Exception e) {
System.out.println(e);
}
}
}
Привет, спасибо за ваш комментарий. Ваше исправление удаляет NullPointer, хотя размер userList по-прежнему равен 0, хотя должен быть равен 1. list.size() = 1 внутри setUserList, но userLisr.size() = 0 в функции входа
В вашем UserInterface возможно ли вызвать public void login(ActionEvent event) throws Exception метод перед userController.setUserList(list);?
Бьюсь об заклад, что еще один экземпляр UserInterface создан при загрузке fxml, поэтому у вас есть еще один пустой экземпляр UserController. Используйте свой UserController в качестве контроллера для login.fxml.
fx:controller на UserController (я думаю, классы находятся в одном пакете).<Pane maxHeight = "-Infinity" maxWidth = "-Infinity" minHeight = "-Infinity" minWidth = "-Infinity" prefHeight = "720.0" prefWidth = "1080.0" styleClass = "main-pane" xmlns:fx = "http://javafx.com/fxml/1" fx:controller = "classmanager.UserController">
UserController: public class UserController {
public ArrayList<User> userList; //should contain one user thomas but gives null pointer
//static ArrayList<User> userList; //this does not return a null pointer
//login.fxml
@FXML
public TextField InputEmailAddress;
@FXML
public TextField InputPassword;
...
userController в UserInterface: public class UserInterface extends Application {
User loggedInUser;
UserRepo userRepo = new UserRepo();
UserController userController;
Connection conn;
UserInterface#start(): public void start(Stage stage) throws Exception {
String connectionURL = "jdbc:derby://localhost:1527/gymManager";
String userName = "root";
String userPassword= "root";
try {
conn = DriverManager.getConnection(connectionURL, userName, userPassword);
if (conn != null){
System.out.println("Connected to the database");
ArrayList<User> list = userRepo.read(conn);
FXMLLoader loader = new FXMLLoader(getClass().getResource("login.fxml"));
Parent root = loader.load();
userController = loader.getController();
userController.setUserList(list);
...
login() из UserInterface и перепишите login() в UserController следующим образом:@FXML
protected void login(ActionEvent event){
try {
System.out.println(userList.size()); //null pointer
} catch (Exception e) {
System.out.println(e);
}
}
ваш ArrayList недоступен в этой функции. вы должны сделать его статическим