I realise that this question has been asked before but none of the solutions have worked for me. I am starting a thread from my controller, and from there the thread gets some data from my database. The thread sends the data to my interface which is implemented in the controller. I get a null pointer exception when trying to access any of my JavaFX elements from there.
Here is my controller:
public class SettingsPage implements PrizeReceiver{
@FXML
AnchorPane settingsAnchor;
@FXML
ListView<String> prizeList;
@FXML
TextField prizeField;
@FXML
Button load;
void init(AnchorPane rootPane){
BasicConfigurator.configure();
AnchorPane root = null;
try {
File file = new File(System.getProperty("user.dir") + "/src/main/res/settings.fxml");
root = FXMLLoader.load(file.toURI().toURL());
} catch (IOException e) {
e.printStackTrace();
}
if (root != null) {
rootPane.getChildren().setAll(root);
}
initPrizeList();
}
private void initPrizeList() {
GetPrizesThread getPrizesThread = new GetPrizesThread(Database.firebaseDatabase, this);
getPrizesThread.getThread().start();
}
@FXML
void addPrize(){
Database.createPrize(prizeField.getText());
}
@Override
public void receivePrizes(ArrayList<String> prizes) {
ObservableList<String> items = FXCollections.observableArrayList();
items.addAll(prizes);
//Iv'e tried this if else with every fxml object and always prints null
if(prizeField==null){
System.out.println("NULL");
}else {
prizeList.getItems().addAll(items);
}
}
}
Here is the Thread:
public class GetPrizesThread implements Runnable {
private boolean finished = false;
private final Thread thread;
private FirebaseDatabase firebaseDatabase;
private PrizeReceiver prizeReceiver;
GetPrizesThread(FirebaseDatabase firebaseDatabase, PrizeReceiver prizeReceiver){
this.firebaseDatabase = firebaseDatabase;
this.prizeReceiver = prizeReceiver;
thread = new Thread(this);
}
@Override
public void run() {
ArrayList<String> prizes = new ArrayList<>();
DatabaseReference databaseReference = firebaseDatabase.getReference("prizes");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
HashMap map = (HashMap) snapshot.getValue();
Set keySet = map.keySet();
ArrayList<String> listOfKeys = new ArrayList<String>(keySet);
prizes.clear();
prizes.addAll(listOfKeys);
finished = true;
}
@Override
public void onCancelled(DatabaseError error) {
finished = true;
}
});
while(!finished) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
prizeReceiver.receivePrizes(prizes);
}
Thread getThread() {
return thread;
}
}
Here is the FXML file(built with scene builder):
<AnchorPane fx:id="settingsAnchor" prefHeight="454.0" prefWidth="700.0"
xmlns="http://javafx.com/javafx/8.0.161" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="SettingsPage">
<children>
<GridPane layoutX="-2.0" layoutY="-1.0" prefHeight="400.0" prefWidth="600.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ListView fx:id="prizeList" prefHeight="400.0" prefWidth="246.0" GridPane.rowSpan="3">
<GridPane.margin>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
</GridPane.margin>
</ListView>
<Button mnemonicParsing="false" onAction="#addPrize" text="Add Prize" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="8.0" top="40.0" />
</GridPane.margin>
</Button>
<TextField fx:id="prizeField" promptText="Prize Name" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="15.0" left="8.0" right="8.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
When I don't have the if/else in place this is my error:
Exception in thread "Thread-5" java.lang.NullPointerException
at SettingsPage.receivePrizes(SettingsPage.java:74)
at GetPrizesThread.run(GetPrizesThread.java:59)
at java.lang.Thread.run(Thread.java:748)
line 74 is
prizeList.getItems().addAll(items);
Thanks for any help.
GetPrizesThread?java.awt.TextFieldinstead ofjavafx.scene.control.TextFieldinSettingsPageclass.prizeListorprizeFieldthat isnull? Anyways, check that your controller imported the correct classes for the controls.