这是基本的fxml文件:
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.github.parboiled1.grappa.debugger.basewindow.BaseWindowUi">
<top>
<MenuBar BorderPane.alignment="CENTER">
<Menu mnemonicParsing="false" text="File">
<MenuItem mnemonicParsing="false"
text="New window" onAction="#newWindowEvent"/>
<MenuItem mnemonicParsing="false"
text="Close" onAction="#closeWindowEvent"/>
</Menu>
</MenuBar>
</top>
<center>
<Label text="Hello"/>
</center>
</BorderPane>
BaseWindowUI
类非常简单:
public class BaseWindowUi
{
private BaseWindowPresenter presenter;
public void init(final BaseWindowPresenter presenter)
{
this.presenter = presenter;
}
@FXML
void newWindowEvent(final ActionEvent event)
{
presenter.handleNewWindow();
}
@FXML
public void closeWindowEvent(final ActionEvent event)
{
presenter.handleCloseWindow();
}
}
演讲者也是:
public final class BaseWindowPresenter
{
private final BaseWindowFactory windowFactory;
public BaseWindowPresenter(final BaseWindowFactory windowFactory)
{
this.windowFactory = windowFactory;
}
public void handleCloseWindow()
{
windowFactory.close(this);
}
public void handleNewWindow()
{
windowFactory.createWindow();
}
}
// Interface...
public interface BaseWindowFactory
{
void createWindow(Stage stage);
default void createWindow()
{
createWindow(new Stage());
}
void close(BaseWindowPresenter presenter);
}
// Implementation...
public final class DefaultBaseWindowFactory
implements BaseWindowFactory
{
private static final AlertFactory ALERT_FACTORY = new AlertFactory();
private static final URL MAIN_WINDOW_FXML;
static {
try {
MAIN_WINDOW_FXML = DefaultBaseWindowFactory.class.getResource(
"/baseWindow.fxml");
if (MAIN_WINDOW_FXML == null)
throw new IOException("base window fxml not found");
} catch (IOException e) {
ALERT_FACTORY.showError("Fatal error", "cannot load base FXML", e);
throw new ExceptionInInitializerError(e);
}
}
private final Map<BaseWindowPresenter, Stage> windows
= new HashMap<>();
private final AtomicInteger windowCount = new AtomicInteger();
@Override
public void createWindow(final Stage stage)
{
final FXMLLoader loader = new FXMLLoader(MAIN_WINDOW_FXML);
final Pane pane;
try {
pane = loader.load();
} catch (IOException e) {
ALERT_FACTORY.showError("Fatal error", "unable to create window",
e);
return;
}
final BaseWindowPresenter presenter = new BaseWindowPresenter(this);
final BaseWindowUi ui = loader.getController();
ui.init(presenter);
stage.setScene(new Scene(pane));
stage.setTitle("window " + windowCount.getAndIncrement());
windows.put(presenter, stage);
stage.show();
}
@Override
public void close(final BaseWindowPresenter presenter)
{
windows.get(presenter).close();
}
}
public final class TestApp
extends Application
{
private final BaseWindowFactory factory = new DefaultBaseWindowFactory();
@Override
public void start(final Stage primaryStage)
throws Exception
{
factory.createWindow(primaryStage);
}
public static void main(final String... args)
{
launch(args);
}
}
初级阶段
primaryStage唯一的特殊之处在于(与任何其他阶段不同),它是由JavaFX系统创建的,而不是由应用程序创建的。但除此之外,初级阶段的行为与其他阶段一样。
有一个与应用程序生命周期相关的阶段相关规则:
您提供的代码没有引入任何新的线程,它只是使用JavaFX系统传递给它的线程(JavaFX应用程序线程)。因此,所提供的代码永远不会违反上述规则(正如Vitomir在他的评论中指出的那样)。
您的DefaultBaseWindowFactory createWindow方法应该只在JavaFX应用程序线程上运行,因此您不需要并发实用程序(如AtomicInteger)来封装窗口的数量,一个简单的整数就足够了,因为只有一个线程在JavaFX应用程序线程上操作读写该值。
如果您引入了创建新线程的新代码(您编写的代码或从库中生成的代码),那么请注意这些代码不要修改活动场景图中的对象,也不要试图直接从另一个线程创建窗口(如果有疑问,您可以通过system.out.println(thread.getname()
)轻松地检查正在执行的线程。如果您最终使用了一些多线程代码,请使用platform.runlater()
包装对操作SceneGraph中的节点或创建新窗口的函数的调用,或者使用JavaFX并发实用程序来管理并发服务。
我有一个小型Java桌面应用程序,没有任何图形用户界面。我使用蚂蚁来开发、运行、构建和发布它。我没有为它创建一个jar文件。我使用一个. sh文件来启动/运行它,并在发行版中附加JRE。 现在我在上面添加了一个简单的JavaFX2GUI。我仍然可以用Ant开发、运行、构建和发布。JavaFX的Ant文件中没有特殊的目标或添加。发布后,我无法再使用现有的.sh文件运行它。我收到以下错误: 线程"ma
问题内容: 我想在关闭JavaFX应用程序之前保存文件。 这就是我在中设置处理程序的方式: 当按下按钮时,控制器将调用: 如果关闭窗口,请单击窗口边框上的红色X(正常方式),然后会收到输出消息“ ”,这是所需的行为。 但是,在调用应用程序时,它会在不调用处理程序的情况下关闭(没有输出)。 如何使控制器使用添加到的处理程序? 问题答案: 如果你看一下在生命周期中的类: 每当启动应用程序时,JavaF
我想在关闭JavaFX应用程序之前保存一个文件。 这就是我在中设置处理程序的方法: 以及当按下按钮时调用的控制器: 如何使控制器使用我添加到中的处理程序?
我在JavaFX中有一个阶段,可以通过多种方式关闭,通过单击红色(X)或通过调用的按钮 无论舞台如何关闭,我都想在舞台关闭之前(或关闭时)执行一个动作。 如果我使用以下代码: 然后,当我单击(X)时调用处理程序,但当我调用<code>myStage.close()</code>时不会调用 这与这个问题讨论的问题相同(有一个关键区别):JavaFX:Stage-close-handler 不同之处在
我想在javafx中从CLI控制台创建尽可能多的阶段,所有这些阶段都是相互独立的。我知道只能有一个应用程序实例,这就是为什么我这样做: 我在屏幕上只看到,并且没有调用SomeStage的构造函数。
javafx中的stage只需要一个场景,而场景只需要一个根节点<所以我想知道这个场景的主要角色是什么?这似乎是一个场景连接了两个侧面,可以直接连接,而无需中间层<我只想理解其中的逻辑。非常感谢。