即使HTMLEditor中有文本,我的.getHtml文本方法也始终返回null

时间:2016-11-07 18:25:41

标签: java javafx nullpointerexception

我正在JavaFX中创建一个基本的文本编辑器,并决定利用HtmlEditor的强大功能。我在工具栏中添加了自己的保存和加载图标供用户使用。

我正在使用FileChooser来允许用户选择要保存的目录,然后程序在所述目录中创建一个文件,然后将HTMLEditor中的数据写入创建的文件中。这是我注意到.getHtmltext()方法继续返回 null 值,即使我在HtmlEditor中输入文本。

我该如何解决这个问题?

SRC代码:

主启动器:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        FXMLLoader fl = new FXMLLoader(getClass().getResource("style.fxml"));

        try {
            AnchorPane ap = fl.load();
            Scene scn = new Scene(ap);
            primaryStage.setScene(scn);
        } catch(Exception e) {

        }
        Control c = fl.getController();
        c.setup(primaryStage);

        primaryStage.setTitle("Postey");
        primaryStage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}

FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.web.HTMLEditor?>


<AnchorPane prefHeight="431.0" prefWidth="631.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="application.Control">
   <children>
      <HTMLEditor fx:id="mainField" htmlText="&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body contenteditable=&quot;true&quot;&gt;&lt;/body&gt;&lt;/html&gt;" layoutX="12.0" layoutY="7.0" prefHeight="409.0" prefWidth="604.0" />
   </children>
</AnchorPane>

最后,控制器:

package application;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.web.HTMLEditor;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class Control {
    @FXML
    private HTMLEditor mainField;

    public void setup(Stage stg) {
        Control c = new Control();

        Node node = mainField.lookup(".top-toolbar");
        if (node instanceof ToolBar) {
            ToolBar bar = (ToolBar) node;

            ImageView graphic = new ImageView(new Image("save.png", 32, 16, true, true));
            graphic.setEffect(new DropShadow());
            Button b2 = new Button("", graphic);
            b2.setOnAction(e -> {
                c.save(stg);
            });
            bar.getItems().add(b2);

            ImageView iv = new ImageView(new Image("load.png", 32, 16, true, true));
            iv.setEffect(new DropShadow());
            Button b1 = new Button("", iv);
            b1.setOnAction(e -> {
                c.load();
            });
            bar.getItems().add(b1);
        }
    }

    private void load() {
        //ignore for now
    }

    private void save(Stage stg) {
        FileChooser fc = new FileChooser();
        FileChooser.ExtensionFilter txtFilter = new FileChooser.ExtensionFilter("txt files (*.txt)", "*.txt");
        FileChooser.ExtensionFilter htmlFilter = new FileChooser.ExtensionFilter("html files (*.html)", "*.html");
        FileChooser.ExtensionFilter cssFilter = new FileChooser.ExtensionFilter("css files (*.css)", "*.css");
        fc.getExtensionFilters().addAll(txtFilter, htmlFilter, cssFilter);

        fc.setInitialDirectory(new File("C://"));
        fc.setTitle("Choose Save Location");
        File f = fc.showSaveDialog(stg);
        String dir = f.getAbsolutePath();

        File omega = new File(dir);
        try {
            FileOutputStream fos = new FileOutputStream(omega);
            PrintWriter pw = new PrintWriter(fos);

            pw.write(mainField.getHtmlText());
            pw.flush();

            pw.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

此外,图标的图片(如果需要):

Save Icon

Load Icon

哦,还有另外一件事。在搜索这个问题的可能解决方案时,我发现我可以使用来自java.util.Optional的名为Optionals的东西我试图使用它们,因为我听说过它们可以除了null值,但它也返回了一个空指针异常。请帮帮我。

1 个答案:

答案 0 :(得分:2)

Control方法中创建setup(...)的全新实例毫无意义。 FXML加载器注入的字段不会在该实例中初始化。只需使用现有实例:

public void setup(Stage stg) {

    Node node = mainField.lookup(".top-toolbar");
    if (node instanceof ToolBar) {
        ToolBar bar = (ToolBar) node;

        ImageView graphic = new ImageView(new Image("save.png", 32, 16, true, true));
        graphic.setEffect(new DropShadow());
        Button b2 = new Button("", graphic);
        b2.setOnAction(e -> {
            save(stg);
        });
        bar.getItems().add(b2);

        ImageView iv = new ImageView(new Image("load.png", 32, 16, true, true));
        iv.setEffect(new DropShadow());
        Button b1 = new Button("", iv);
        b1.setOnAction(e -> {
            load();
        });
        bar.getItems().add(b1);
    }
}