【问题标题】:How to open a text file from package while application is running?应用程序运行时如何从包中打开文本文件?
【发布时间】:2017-09-28 16:59:57
【问题描述】:

我有一个带有按钮的 JavaFX 应用程序,我想打开我已经编写的“帮助文件”,并且我希望它在用户按下按钮时在默认文本编辑器中打开。该文件位于包含主 FX 类、控制器和 FXML 文件的包中。我试图做一些不同的事情来打开文件,但都没有奏效。这是我目前拥有的方法,在我看来它应该有效,但事实并非如此。我究竟做错了什么?里面所有东西的包的名字命名为“nutritionfx”只是为了澄清,这段代码是Controller内部的一个方法。

//method to open help file when help button is pressed
@FXML private void handleHelpButton(ActionEvent event) throws IOException, URISyntaxException {
    URL url = this.getClass().getResource("/nutritionfx/help.txt");
    File file = new File(url.toURI());
    Desktop.getDesktop().edit(file);
}

【问题讨论】:

  • 将资源 uri 包装在 File 中不会使其成为文件。如果资源文件在 jar 中并且编辑器需要一个文件,它将无法访问该文件。我所知道的使资源作为文件可访问的唯一方法是将资源的内容复制到文件中......
  • 那么最好从打包文件中创建一个新文件,然后打开该文件?这会在用户计算机上创建一个新文件吗?
  • 是的,正是,做那个 Trace。

标签: java javafx netbeans fxml embedded-resource


【解决方案1】:

这是一个示例应用程序,它演示了您提出的 Trace 解决方案。

从打包文件创建一个新文件,然后打开该文件

示例应用程序将从与您的应用程序一起打包的资源中读取数据,并将其保存到用户主目录中应用程序目录(名为 `.FileEditor)中的本地文件中。用户可以在文本编辑器中编辑文本并将修改后的文本保存到本地文件中。下次他们运行应用程序时,它将读取和使用修改后的文本,而不是来自打包资源的文本。

import javafx.application.Application;

import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;

public class FileEditor extends Application {

    private static final Path USER_FILE_PATH = Paths.get(
        System.getProperty("user.home"), 
        ".FileEditor"
    );

    private static final String SOURCE_FILE_NAME = "xyzzy.txt";

    @Override
    public void start(Stage stage) throws Exception {
        if (!Files.isDirectory(USER_FILE_PATH)) {
            Files.createDirectory(USER_FILE_PATH);
        }

        Path editableFilePath = Paths.get(USER_FILE_PATH.toString(), SOURCE_FILE_NAME);
        if (!Files.exists(editableFilePath)) {
            Files.copy(
                FileEditor.class.getResourceAsStream(SOURCE_FILE_NAME),
                editableFilePath
            );
        }

        String text = Files.readAllLines(
                editableFilePath
        ).stream()
                .collect(Collectors.joining("\n"));

        TextArea textArea = new TextArea(text);

        MenuItem save = new MenuItem("Save...");
        save.setOnAction(event -> {
            try {
                Files.write(editableFilePath, textArea.getText().getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        MenuItem exit = new MenuItem("Exit");
        exit.setOnAction(event -> stage.hide());
        MenuBar menuBar = new MenuBar(
                new Menu("File", null, save, exit)
        );

        BorderPane layout = new BorderPane();
        layout.setTop(menuBar);
        layout.setCenter(textArea);

        Scene scene = new Scene(layout);
        stage.setScene(scene);
        stage.show();
    }


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

示例源资源xyzzy.txt,与FileEditor.java代码放在同一目录下,由构建系统复制到资源输出打包目录:

You are in a maze of twisty passages, all alike.
xyzzy
You are inside the building.

此示例使用 JavaFX 应用程序中的 TextArea 来编辑文件,但您可以使用以下构造在默认系统文本编辑器中轻松打开:

getHostServices().showDocument(
    editableFilePath.toUri().toURL().toExternalForm()
);

【讨论】:

    猜你喜欢
    • 2013-01-11
    • 2020-02-22
    • 2013-06-09
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多