【发布时间】:2015-07-27 17:31:46
【问题描述】:
我有:2 个 FXML 文件和 2 个控制器。每个 FXML 都合并了控制器。这是打开新 FXML 的代码(当真正的 fxml 运行时,它会打开另一个)
try {
Parent root = FXMLLoader.load(getClass().getResource(
"settings.fxml"));
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.centerOnScreen();
stage.show();
} catch (Exception e) {
e.printStackTrace();
Logger.logCrash("ApplicationScene", e);
}
这是打开的 FXML 文件的控制器
@FXML
public TextField destination;
@FXML
public TextArea view;
@FXML
public TextArea point;
public void initialize() {
destination.appendText("LOL");
view.appendText("LAA");
point.appendText("LOWKAPF");
}
如您所见,在通过初始化方法加载根之后,我在所有声明的字段(FXML-ID'S ARE BOUND!)上附加文本。听起来不错,很棒,但我得到了 NullPointerException。
明确指出: - 我已经将 fxml-ids 绑定到它们相应的组件。 - FXML 文件被正确加载(root 被正确加载,否则初始化方法不起作用)
这与静态访问无关。即使没有静态访问,这也不起作用。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="373.0" prefWidth="518.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="removed">
<children>
<TextField fx:id="destination" layoutX="14.0" layoutY="19.0" prefHeight="25.0" prefWidth="464.0" promptText="Destination of the files" text="ie.: C:\" />
<Text layoutX="14.0" layoutY="57.0" strokeType="OUTSIDE" strokeWidth="0.0" text="moo" wrappingWidth="464.0" />
<TextArea fx:id="point" layoutX="14.0" layoutY="76.0" prefHeight="42.0" prefWidth="464.0" promptText="HI/>
<Text layoutX="14.0" layoutY="131.0" strokeType="OUTSIDE" strokeWidth="0.0" text="meow" wrappingWidth="464.0" />
<TextArea fx:id="view" layoutX="14.0" layoutY="135.0" prefHeight="42.0" prefWidth="464.0" promptText="HI" />
<Text layoutX="14.0" layoutY="191.0" strokeType="OUTSIDE" strokeWidth="0.0" text="m00" wrappingWidth="464.0" />
<Button layoutX="220.0" layoutY="269.0" mnemonicParsing="false" onAction="#initialize" text="Default" />
</children>
</AnchorPane>
哦。好的,所以,我所做的是:
package com.engine.application.content;
import com.engine.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Settings extends Application {
public static void start() {
Application.launch();
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource(
"settings.fxml"));
Scene scene = new Scene(root);
setStageProperties(primaryStage, scene);
}
/**
* Sets the properties of the application
*
* @param stage
* the stage's properties to set
* @param scene
* the scene's properties to set
*/
private void setStageProperties(Stage stage, Scene scene) {
stage.setScene(scene);
stage.setTitle("Test");
stage.centerOnScreen();
stage.setResizable(true);
stage.show();
Logger.log("Launcher", "Set stage properties");
}
}
那我打电话
应用程序.start()
当一个按钮被点击时
这是结果:
Caused by: java.lang.IllegalStateException: Application launch must not be called more than once
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
at javafx.application.Application.launch(Unknown Source)
at xxx.Settings.start(Settings.java:14)
at xxx.openMenu(ApplicationScene.java:43)
... 56 more
顺便说一句,我不会在其他地方称呼它。
编辑: 这是设置应用程序初始化。
public class Settings extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource(
"settings.fxml"));
Scene scene = new Scene(root);
setStageProperties(primaryStage, scene);
System.out.println("YAY");
}
/**
* Sets the properties of the application
*
* @param stage
* the stage's properties to set
* @param scene
* the scene's properties to set
*/
private void setStageProperties(Stage stage, Scene scene) {
stage.setScene(scene);
stage.setTitle("Test");
stage.centerOnScreen();
stage.setResizable(true);
ApplicationScene.settingsMenu = stage;
Logger.log("Launcher", "Set stage properties");
}
}
这是主应用程序 公共类 ApplicationLauncher 扩展应用程序 {
/**
* The main method
*
* @param args
* the arguments given upon start
*/
public static void main(String args[]) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Logger.log("Launcher", "Starting up..");
Parent root = FXMLLoader.load(getClass().getResource(
"ah.fxml"));
Directory directory = new Directory();
// Logger.logError("LOL", "ERROR! LOLOLOL L /n LOL \n LOL LOL");
Scene scene = new Scene(root);
directory.createFolder();
setStageProperties(stage, scene);
Settings.main(null);
Logger.log("Launcher", "Application started up!");
}
/**
* Sets the properties of the application
*
* @param stage
* the stage's properties to set
* @param scene
* the scene's properties to set
*/
private void setStageProperties(Stage stage, Scene scene) {
stage.setScene(scene);
stage.setTitle("Test");
stage.centerOnScreen();
stage.setResizable(true);
stage.show();
Logger.log("Launcher", "Set stage properties");
}
}
结果:
Caused by: java.lang.IllegalStateException: Application launch must not be called more than once
别无他法。 (顺便说一句。做 Settings.main(null); 与 Settings.launch(); 相同)
重新思考这个概念后
做到了:
new Settings().start(new Scene());
【问题讨论】:
-
您不需要静态访问。确保为您的
FXML文档填写了fx:id="something"。 “某事”部分必须正是您的变量名。因此,在您的 FXML 中,您有fx:id="destination",而在您的控制器中,您有@FXML public TextField destination;。它们也必须与类型匹配。并且不要忘记让你的 FXML 使用你的控制器作为控制器,否则事情不会被正确初始化。 -
如果你把字段设为
static,那肯定不行。如果更正后仍然无法正常工作,那么您还有其他错误。发布 FXML 文件,否则我们只能猜测这些错误是什么(@SnakeDoc 做出了一些很好的猜测,但您需要显示您的代码才能知道其中哪些(如果有)是问题)。 -
@SnakeDoc FX id 是正确的。
-
编辑帖子以显示打开窗口的 FXML 文件
-
@Sh0ck 请粘贴您的完整控制器以及
extends Application或调用launch()静态方法的类文件。