I'll make an Answer of the two Comments by Slaw, here & here.
JavaFX “magic”
JavaFX is a sophisticated framework that does quite a bit of “magic” beyond what you see in your own source code.
One bit of that magic is that when your JavaFX app launches, your subclass of Application
is automatically instantiated via reflection.
So your line of code, MyScreen screen = New MyScreen();
is superfluous, and should be deleted. The JavaFX framework is already making an instance of MyScreen
as your subclass of Application
. So your app has two instances of MyScreen
going, the one implicitly created by the JavaFX framework, and another one created by you in that line of code.
This explains why you fail in getting the value of userText
field. Your code is making a call to your instance of MyScreen
, not the JavaFX framework’s instance of MyScreen
. The userText
field was indeed set, but was set in the latter, not the former.
this
hack
If you really want to track state within your app in your given approach, I have seen a hack where people make a Singleton reference to the implicitly instantiated object of their Application
subclass. They add a static
var on their subclass of Application
, a var of the type of the subclass. Then in their Application#start
override implementation, they assign this
to that var.
public class MyScreen extends Application {
public static MyScreen myInstanceOfMyScreen;
private String userText;
@Override
private void start(Stage stage) {
…
this.myInstanceOfMyScreen = this ; // A hack, not necessarily recommended.
}
public getUserText() {
return userText;
}
Then other classes can access that static
singleton.
// Some code in some other class
String userText = MyScreen.myInstanceOfMyScreen.getUserText() ;
But this approach likely indicates a poor design within your app.
JavaFX lifecycle
To learn more about the lifecycle of a JavaFX app, see my lengthy Answer on another Question.
Caveat: I am not an expert on JavaFX. For more expertise, look for posts by jewelsea, by Slaw, by James_D, and others. And read the documentation.
GUI app versus console app
Your approach in designing your app seems peculiar, running the JavaFX-based GUI app as a subroutine of a larger "outer" app.
A GUI app is standalone. The lifecycle of the GUI should be the lifecycle of the app. If all the elements of the GUI have been closed, with no more windows and no more menu bar, then the app should end.
The fact that you named your Application
subclass MyScreen
shows how you are thinking of JavaFX as being only a part of your app. Instead you should be thinking of JavaFX as your entire app.
If your goal is build a console app that gathers input from a user, then use the console-related classes of Java such as Scanner
to interact with the user on the console. Trying to mix a GUI app with a console app makes no sense, not from the architectural design of modern operating systems such as macOS, Windows, Linux, etc.
The one exception would be console-oriented environment that wants to run a GUI-style within that terminal screen. Such apps are known as text-based user-interface, made famous by Microsoft with their COW (Character-Oriented Windows) apps such as Microsoft Works for MS-DOS. But such apps are meant to run within a terminal screen/window. In contrast, JavaFX apps are meant to run within a graphical environment such as macOS/Windows/Linux/etc. FYI, the Java ecosystem does offers some frameworks for build text-based UI apps, such as Lanterna.
Communicating data
If you need to share the user’s input beyond the limits of the GUI, use an external system. For example, post the data to a message queue, send an email, insert into a database, write a file to storage.
Example app
Here is an example JavaFX app that:
- Gathers input from the user.
- Reports that data to a message queue, sends an email, and writes to a database.
- Quits/exits the app.

Notice that the GUI remains visible while reporting to that queue, email, and database. If anything goes wrong, you can use that GUI to notify the user of a problem.
package work.basil.example.exfxgatherinput;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
public class GatherInputApp extends Application
{
@Override
public void start ( Stage stage ) throws IOException
{
// Scene
Scene scene = this.makeScene ( );
// Stage
stage.setTitle ( "Give me your input" );
stage.setHeight ( 300 );
stage.setWidth ( 500 );
stage.setScene ( scene );
stage.show ( );
}
private Scene makeScene ( )
{
// Data input
Label inputLabel = new Label ( "Favorite color:" );
TextField inputTextField = new TextField ( );
HBox inputBox = new HBox ( );
inputBox.setAlignment ( Pos.CENTER );
inputBox.getChildren ( ).addAll ( inputLabel , inputTextField );
inputBox.setSpacing ( 10 );
// Submit data
Button button = new Button ( );
button.setText ( "Submit input, quit app" );
button.setOnAction ( ( event ) ->
{
String favoriteColor = inputTextField.getText ( );
System.out.println ( "Reporting input to a message queue… " + favoriteColor );
System.out.println ( "Sending input in an email… " + favoriteColor );
System.out.println ( "Writing input to a database… " + favoriteColor );
Platform.exit ( ); // Ends the JavaFX app, after firing hooks for app-shutdown.
} );
VBox vbox = new VBox ( inputBox , button );
vbox.setPadding ( new Insets ( 20 , 20 , 20 , 20 ) );
vbox.setSpacing ( 10 );
vbox.setAlignment ( Pos.CENTER );
return new Scene ( vbox );
}
public static void main ( String[] args ) { launch ( ); }
}
When run:
Reporting input to a message queue… purple
Sending input in an email… purple
Writing input to a database… purple
Process finished with exit code 0
By the way, exiting a GUI app programmatically is considered rude. In a graphical environment, the user is in charge. Generally, the app should remain open and running until the user decides to quit/exit.