有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在javaFX中使用FileeChooser创建新文件并将数据保存在文件中?

我需要通过对话框保存文件。对话框打开但文件本身未保存,如何修复? 代码:

    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Save");
    fileChooser.setInitialFileName("save file");
    fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("All Files", "*.*"));
    //Adding action on the menu item
    save.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {


            //Opening a dialog box
            fileChooser.getExtensionFilters()
                    .addAll(
                            new FileChooser.ExtensionFilter("TXT files (*.TXT)", "*.TXT"),
                            new FileChooser.ExtensionFilter("txt files (*.txt)", "*.txt")
                    );
            fileChooser.showSaveDialog(primaryStage);

        }
    });

共 (3) 个答案

  1. # 1 楼答案

    下面是一个小例子,如果您想创建一个具有特定文件名(TextField)、文件扩展名(ComboBox)和目标目录(DirectoryChooser)的新文件:

    控制器类:

    package sample;
    
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.TextField;
    import javafx.stage.DirectoryChooser;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.ResourceBundle;
    
    public class Controller implements Initializable {
    
        @FXML
        private Button
                saveBtn;
        @FXML
        private TextField
                fileNameTextField,
                directoryTextField;
        @FXML
        private ComboBox<String>
                fileExtensionComboBox;
    
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            fileExtensionComboBox.getItems().addAll(".txt", ".json", ".xml");
    
            saveBtn.disableProperty().bind(fileNameTextField.textProperty().isEmpty()
                    .or(fileExtensionComboBox.getSelectionModel().selectedItemProperty().isNull()
                            .or(directoryTextField.textProperty().isEmpty())));
        }
    
        @FXML
        public void handleChangeDirectoryBtnClick() {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            File selectedDirectory = directoryChooser.showDialog(null);
            if (selectedDirectory != null) directoryTextField.setText(selectedDirectory.getAbsolutePath());
        }
    
        @FXML
        public void handleSaveBtnClick() {
            Path file = Paths.get(directoryTextField.getText(), fileNameTextField.getText().trim() + fileExtensionComboBox.getSelectionModel().getSelectedItem());
            if(!Files.exists(file)) { {
                try {
                    Files.createFile(file.toAbsolutePath());
                    //...
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    FXML文件:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.ComboBox?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.ColumnConstraints?>
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.RowConstraints?>
    
    <GridPane hgap="3.0" vgap="3.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
      <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" />
          <ColumnConstraints hgrow="SOMETIMES" />
      </columnConstraints>
      <rowConstraints>
        <RowConstraints vgrow="SOMETIMES" />
          <RowConstraints vgrow="SOMETIMES" />
          <RowConstraints vgrow="SOMETIMES" />
          <RowConstraints vgrow="SOMETIMES" />
          <RowConstraints vgrow="SOMETIMES" />
      </rowConstraints>
       <children>
          <Label text="File Name:" />
          <TextField fx:id="fileNameTextField" GridPane.rowIndex="1" />
          <Label text="File Extension:" GridPane.columnIndex="1" />
          <ComboBox fx:id="fileExtensionComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
          <Label text="Directory:" GridPane.rowIndex="2" />
          <AnchorPane GridPane.columnSpan="2" GridPane.rowIndex="3">
             <children>
                <TextField fx:id="directoryTextField" editable="false" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="60.0" />
                <Button onAction="#handleChangeDirectoryBtnClick" text="Change" AnchorPane.rightAnchor="0.0" />
             </children>
          </AnchorPane>
          <HBox alignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="4">
             <children>
                <Button fx:id="saveBtn" onAction="#handleSaveBtnClick" text="Save" />
             </children>
          </HBox>
       </children>
       <padding>
          <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
       </padding>
    </GridPane>
    

    预览:

    preview

  2. # 2 楼答案

    文件选择器中的过滤器仅用于显示现有文件。如果您想用某个扩展名保存文件,则需要以下内容:

    String fileName = file.toString();
    if (!fileName.endsWith(".java"))
    fileName += ".java";
    
  3. # 3 楼答案

    FileChooser不会在存储设备上创建文件,也不会修改文件(如果存在)

    这只是一种让用户通过保存对话框确定的File实例的方法。用户选择文件后,您需要自己保存数据:

    File selectedFile = fileChooser.showSaveDialog(primaryStage);
    if (selectedFile != null) {
        // dialog closed by selecting a file to save the data to
    
        // write data here yourself, e.g.
        try (BufferedReader br = Files.newBufferedReader(selectedFile.toPath(), StandardCharsets.UTF_8)) {
            br.write("Hello World!\n");
        }
    }
    

    如果写入文件可能需要很长时间,则应将写入逻辑移动到后台线程,以避免冻结GUI