JavaFX无法编辑文本

时间:2015-07-27 17:31:47

标签: java xml javafx fxml

我有: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");
    }

正如您所看到的,我在通过initialize方法加载根之后,在所有声明的字段(FXML-ID' S ARE BOUND!)上附加文本。听起来不错,但是我得到了一个N​​ullPointerException。

明确指出事情: - 我已经将fxml-id绑定到相应的组件。 - 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");
    }

}

然后我打电话给 Application.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

我没有在其他地方称它为btw。

修改 这是设置应用程序初始化。

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扩展了Application {

/**
 * 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(); lol)相同

重新思考概念后

这样做了:

new Settings().start(new Scene());

2 个答案:

答案 0 :(得分:1)

在与@SnakeDoc讨论了很长时间之后,我们终于设法解决了这个问题。

对于遇到同样问题的人:

new Settings().start(new Scene());

这样做。由于start方法基本上可以完成所有操作(加载FXML等),因此只需要那行代码。

如果您仍然遇到困难,请确保FXID与要连接的实例的变量名相同。

答案 1 :(得分:0)

这是嵌入在主应用程序控制器中的一些逻辑的示例:

// somewhere in the declarations for the controller class
private Parent webViewRoot;
private Stage webViewStage;
private Scene webViewScene;
private Path webViewFXML;

// somewhere in the logic section of the controller class
public void handleToggleWebView(final ActionEvent event) {
    initWebView();
    if (toggleWebView.isSelected()) {
        webViewStage.show();
    } else {
        webViewStage.close();
    }
}

private void initWebView() {
    if (webViewFXML == null) {
        webViewFXML = Paths.get(ConfigurationManager.ProdFeature.getHomeDirectory() 
                + File.separator + "resources" + File.separator + "WebView.fxml");
    }
    if (webViewRoot == null) {
        try {
            final FXMLLoader fxmlloader = new FXMLLoader(webViewFXML.toUri().toURL());
            fxmlloader.setRoot(webViewRoot);
            fxmlloader.setController(WebViewController.getInstance());
            webViewRoot = fxmlloader.load();
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            final Dialog exceptionDialog = new Dialog.Builder(DialogType.EXCEPTION)
            .setTitle("ERROR").setHeaderText("Failed to load WebView FXML.")
            .setException(e).build();
            exceptionDialog.showAndWait();
            return;
        }
    }
    if (webViewScene == null) {
        webViewScene = new Scene(webViewRoot);
    }
    if (webViewStage == null) {
        webViewStage = new Stage();
        try {
            // add icon
            Path icon = Paths.get(ConfigurationManager.ProdFeature.getHomeDirectory() 
                    + File.separator + "resources" + File.separator + "logo.png");
            webViewStage.getIcons().add(new Image(icon.toUri().toURL().toExternalForm()));
        } catch (Exception e) {
            // ignore
        }

        StringBuilder title = new StringBuilder();
        title.append(ConfigurationManager.ProdFeature.getString("prodfeature.program.name"));
        title.append(" WebView | version ");
        title.append(ConfigurationManager.ProdFeature.getString("prodfeature.program.version"));
        webViewStage.setTitle(title.toString());
        webViewStage.setScene(webViewScene);
        webViewStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(final WindowEvent we) {
                we.consume();
                toggleWebView.setSelected(false);
                webViewStage.close();
            }
        });
        webViewStage.initOwner(productTitleLabel.getParent().getScene().getWindow());
    }
}

在此示例中,所有这些逻辑都在您的主控制器类中。按下Button toggleWebView;按钮后,它会调用handleToggleWebView()方法(在FXML中设置为onAction)。如果它尚未构建,则反过来加载新窗口,然后显示或隐藏它。新窗口有自己的FXML文件,它有自己的控制器,然后用于处理按钮点击事件等...仅适用于该窗口。