Solution for Scene.getFocusOwner() returning null inseatd of node from Scene
is Given Below:
I have a JavaFX application. The way it works right now is it creates a GridPane
and calls a function that takes an Arraylist of an object, where each object consists of a Label
, TextField
, and Label
in that order. Said function adds all these nodes individually to the GridPane
after which the GridPane
is added to a Scene
. Before I set up the Stage
, I try to set up event handlers for all the TextField
objects in a separate function. In there I try to get the Textfield
in which the cursor is currently waiting, to decide what action a Textfield
will take. I try to use Scene.getFocusOwner in a separate function to get the TextField currently selected but it always returns Null, when it should return an object that I can cast to TextField
(even after the application has started). The relevant code is below:
//How the start function looks
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Warehouse Form");
ArrayList<FormRow> entryRows = new ArrayList<>();
//each array holds same number of Strings
String defLabels[] = {"....", "....", ....};
String defTextEntry[] = {"....", "....", ....};
String defConfLabels[] = {"....", "....", ....};
GridPane g = runDefaultForm(entryRows,defLabels, defTextEntry, defConfLabels);
final Scene sc = new Scene(g,500,600);
setEntryEventHandlers(g, sc, primaryStage, entryRows);
primaryStage.setScene(sc);
primaryStage.show();
}
Inside ‘setEventEntryHandlers’ function
public void setEntryEventHandlers(GridPane g, Scene sc, Stage st, ArrayList<FormRow> formRows){
int row = 0, col = 0;
TextField curTextEntry = null;
TextField nextTextEntry = null;
Label curConfLabel = null;
Label curLabel = null;
//Iterate through every field and set event handler, goes down via row
for(int i = 0; i < fieldsAdded; i++){
curLabel = (Label)getNodeFromGrid(g, i, col);//Gets Label from coordinates
curTextEntry = (TextField) getNodeFromGrid(g, i, col + 1);//Gets Entry Textfield from Coordinates
nextTextEntry = (TextField)getNodeFromGrid(g,i + 1, col + 1 );//Gets the Next Text Entry from coordinates
curConfLabel = (Label)getNodeFromGrid(g, i, col + 2);//
//function call that contains Scene.getFocusOwner
TextField tempFocus = getFocusFromGrid(g, sc, formRows, userSelectedCoordinates);
if(tempFocus == null){
System.out.println("TEXTFIELD IS NULL BABY");
}
else{
System.out.println("ALL IS GOOD");
}
.
.
.
}
}
The function where Scene.getFocusOwner is called…
public TextField getFocusFromGrid(GridPane g, Scene sc, ArrayList<FormRow> rows, int[] v){
Node tempNode = sc.getFocusOwner();
//try to find the node in children of GridPane, it will never find it because it is null
if(g.getChildren().contains(tempNode)){
System.out.println("FOUND THIS");
}
else{
System.out.println("NOTHING WAS FOUND");
}
return (TextField)tempNode;
}
So that call for Scene.getFocusOwner always returns null, I’m not even sure if I set all of this uuprightor if I can use the function call two functions deep (so to speak) from the start function. Any help would be appreciated.
Just move setEntryEventHandlers
so it’s invoked after show:
primaryStage.setScene(sc);
primaryStage.show();
setEntryEventHandlers(g, sc, primaryStage, entryRows);
What you’re doing is invoking setEntryEventHandlers when primaryStage is not yet a window, so focus will be null. For better results, you should invoke it on the primaryStage.onShown event: primaryStage.setOnShown(e-> setEntryEventHandlers(g, sc, primaryStage, entryRows));
and after setting onShown handler, you show the stage and should work fine.