我将对Slaw,here&Amp;here的两条 comments 做出回答.
JavaFX “magic”
JavaFX是一个复杂的框架,它比您在您自己的源代码中看到的要"神奇"得多.
其中一个神奇之处在于,当您的JavaFX应用程序启动时,Application
的子类将通过reflection自动实例化.
所以你的代码行MyScreen screen = New MyScreen();
是多余的,应该删除.JavaFX框架已经创建了MyScreen
的一个实例作为Application
的子类.因此,您的应用程序有两个MyScreen
Go实例,一个由JavaFX框架隐式创建,另一个由您在该行代码中创建.
这就解释了为什么您无法获得userText
字段的值.您的代码调用的是MyScreen
的your实例,而不是JavaFX框架的MyScreen
实例.userText
字段确实设置了,但设置在后者,而不是前者.
this
hack
如果您really想要在您的给定方法中跟踪应用程序中的状态,我见过一个黑客攻击,其中人们对其Application
子类的隐式实例化对象进行了Singleton次引用.他们在子类Application
上添加static
变量,这是子类类型的变量.然后,在其Application#start
覆盖实现中,它们将this
赋值给该变量.
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;
}
然后其他类就可以访问这static
个单例.
// Some code in some other class
String userText = MyScreen.myInstanceOfMyScreen.getUserText() ;
但这种方法很可能表明您的应用程序中存在糟糕的设计.
JavaFX生命周期
要了解有关JavaFX应用程序生命周期的更多信息,请参阅另一个问题的my lengthy Answer.
警告:我不是JavaFX方面的专家.要获得更多专业知识,请查找jewelsea、Slaw、James_D和其他方面的帖子.并阅读the documentation.
GUI app versus console app
您设计应用程序的方法似乎很奇怪,将基于JavaFX的图形用户界面应用程序作为更大的"外部"应用程序的子 routine 运行.
图形用户界面应用程序是独立的.图形用户界面的生命周期应该是应用程序的生命周期.如果图形用户界面的所有元素都已经关闭,没有更多的窗口和菜单栏,那么应用程序应该结束.
您将Application
个子类命名为MyScreen
这一事实表明,您认为JavaFX只是您应用程序的一部分.相反,您应该将JavaFX作为您的entire应用程序.
如果您的目标是构建一个从用户那里收集输入的控制台应用程序,那么可以使用与控制台相关的Java类(如Scanner
)在控制台上与用户交互.试图将图形用户界面应用程序与控制台应用程序混合在一起是没有意义的,从MacOS、Windows、Linux等现代操作系统的架构设计来看是没有意义的.
唯一例外是希望在终端屏幕中运行图形用户界面的面向控制台的环境.这类应用程序被称为text-based user-interface,微软因其COW(Character-Oriented Windows)应用程序(如Microsoft Works for MS-DOS)而闻名.但这类应用程序应该在终端屏幕/窗口中运行.相反,JavaFX应用程序应该在MacOS/Windows/Linux/等图形环境中运行.仅供参考,Java生态系统确实提供了一些框架来构建基于文本的UI应用程序,例如Lanterna.
通信数据
如果您需要共享超出图形用户界面限制的用户输入,请使用外部系统.例如,将数据发布到message queue,发送邮箱,插入数据库,将文件写入存储.
Example app
以下是一个JavaFX应用程序示例:
- 收集来自用户的输入.
- 将数据报告到消息队列、发送邮箱并写入数据库.
- 退出/退出应用程序.
请注意,在向该队列、邮箱和数据库报告时,该图形用户界面保持可见.如果出现任何错误,您可以使用该图形用户界面来通知用户问题.
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 ( ); }
}
运行时:
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
顺便说一句,以编程方式退出图形用户界面应用程序被认为是粗鲁的.在图形环境中,用户负责.一般来说,应用程序应该保持打开和运行,直到user人决定退出/退出.