JFileChooser 和复制文件

JFileChooser and copying files

我正在为 class 做作业,有几个问题希望得到帮助。该作业是一个 GUI,允许用户 select 复制文件并选择要将文件复制到的位置。

我已经完成了作业,但有几件事我想看看是否可以更改...

当 select 编辑源文件时,我只想在标签中显示源文件的名称,但是程序需要完整路径才能复制文件每次我尝试将其切换为只显示文件名时,程序不会 运行 因为它不知道文件的位置。第二个问题,有没有办法让程序自动将文件复制为 .bak 文件...假设源文件是一个文本文件,用户选择一个目标文件夹并点击复制,它会保存一个同名的文件,但.bak 扩展名?

我将有问题的代码放在 *** 之间,并留下了我试图用来仅显示文件名的代码并将其注释掉。感谢您的帮助!!

public class CopyFile extends JFrame{

private JFileChooser fc;
private JButton copyButton;
private JButton chooseFileButton;
private JButton destinationButton;
private File workingDirectory;
private JLabel sourceLabel;
private JLabel destinationLabel;
private JTextField sourceText;
private JTextField sourceFileText;
private JTextField destinationText;

public static void main(String [] args) {
    CopyFile go = new CopyFile();
    go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    go.setSize(500, 150);
    go.setVisible(true);
}

public CopyFile() {
    super("Copy a text file");
    setLayout(new GridLayout(3, 3, 5, 5));
    fc = new JFileChooser();

    //Open dialog box inside project folder to make easier to find files
    workingDirectory = new File(System.getProperty("user.dir"));
    fc.setCurrentDirectory(workingDirectory);
    //create labels and buttons for window
    chooseFileButton = new JButton("CHOOSE SOURCE FILE");
    destinationButton = new JButton("DESTINATION FOLDER");
    copyButton = new JButton("COPY FILE");      
    sourceLabel = new JLabel("SOURCE FILE: ");
    sourceText = new JTextField(10);
    sourceText.setEditable(false);
    destinationLabel = new JLabel("DESTINATION: ");
    destinationText = new JTextField(10);

    //add everything to JFrame  
    add(sourceLabel);
    add(sourceText);
    add(chooseFileButton);  
    add(destinationLabel);
    add(destinationText);
    add(destinationButton);
    add(copyButton);

    //Create TheHandler object to add action listeners for the buttons.
    TheHandler handler = new TheHandler();
    chooseFileButton.addActionListener(handler);
    destinationButton.addActionListener(handler);
    copyButton.addActionListener(handler);
}

//Inner class to create action listeners    
private class TheHandler implements ActionListener {
    public void actionPerformed(ActionEvent event) {
        int returnVal;
        String selectedFilePath;
        File selectedFile;

******************************************************************************      
        //Selecting a source file and displaying what the user is doing.
        if(event.getSource() == chooseFileButton) {     
            returnVal = fc.showOpenDialog(null);
            //Set the path for the source file. 
            if(returnVal == JFileChooser.APPROVE_OPTION) {  

  /*The two next lines of code are what I was trying to do to get only the
  file name but I get a whole page of errors, mainly I think it's saying no 
  such file exists*/
                //selectedFile = fc.getSelectedFile();
                //sourceText.setText(selectedFile.getName());   
                selectedFilePath = fc.getSelectedFile().getAbsolutePath();
                sourceText.setText(selectedFilePath);
            }       
        }//end if

******************************************************************************          
        //Handle destination button.
        if(event.getSource() == destinationButton) {
            returnVal = fc.showSaveDialog(null);
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                 selectedFilePath = fc.getSelectedFile().getAbsolutePath();
                destinationText.setText(selectedFilePath);
            }               
        }//end if

        //Handle copy button
        if(event.getSource() == copyButton) {
            File sourceFile = new File(sourceText.getText());
            File destinationFile = new File(destinationText.getText());
            Path sourcePath = sourceFile.toPath();
            Path destinationPath = destinationFile.toPath();        
            try {
                Files.copy(sourcePath,  destinationPath);
            } catch (IOException e) {
                e.printStackTrace();
            }   
        }//end if

    }//end actionPerformed      
}//end TheHandler class
}//end class

When selecting the the source file I want ONLY the name of the source file to show up in the Label but, the program needs the entire path in order to copy the file and every time I tried to switch it to show the file name only the program won't run because it doesn't know where the file is located.

您可以使用 File#getName,这将 return 文件名并将其用作标签的文本,但保留对原始 File 的引用。您不应该使用标签的文本来生成新的 File 引用,只需保留对源 File 和目标 File 以及实例字段

的引用

Second question, is there anyway to make the program copy a file automatically as a .bak file...Say the source file is a text file and the user picks a destination folder and hits copy and it saves a file with the same name but a .bak extension?

String name = selectedFile.getName();
name = name.substring(0, name.lastIndexOf("."));
name += ".bak";
File destinationFile = new File(destinationPath, name);

会将 selectedFile 的扩展名更改为 .bak,但您可能应该添加一个检查以查看它是否具有以

开头的扩展名

You have to keep the source and destination file paths as Files, not Strings. Modify your code of TheHandler class as follows.

  1. 添加 selectedSourceFileselectedDestinationFile 本地字段。

    private class TheHandler implements ActionListener {
        private File selectedSourceFile;
        private File selectedDestinationFile;
    
  2. 选择文件时更新它们并设置文件名而不是文本字段的路径。

源文件按钮

        if (event.getSource() == chooseFileButton) {
            returnVal = fc.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                selectedSourceFile = fc.getSelectedFile();
                sourceText.setText(selectedSourceFile.getName());
            }
        }

目标按钮

        if (event.getSource() == destinationButton) {
            returnVal = fc.showSaveDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                selectedDestinationFile = fc.getSelectedFile();
                destinationText.setText(selectedDestinationFile.getName());
            }
        }
  1. 复制时使用selectedSourceFileselectedDestinationFile

        if (event.getSource() == copyButton) {
            Path sourcePath = selectedSourceFile.toPath();
            Path destinationPath = selectedDestinationFile.toPath();
            try {
                Files.copy(sourcePath, destinationPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

Now you are done the first requirement. You can make backfile when selecting the destination file. So, add your code to make backup file when selecting destination button.

        if (event.getSource() == destinationButton) {
            returnVal = fc.showSaveDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                selectedDestinationFile = fc.getSelectedFile();
                destinationText.setText(selectedDestinationFile.getName());

                //copy backup
                String name = selectedSourceFile.getName();
                name = selectedSourceFile.getName().substring(0, name.lastIndexOf(".")) + ".bak";
                File destinationFile = new File(selectedDestinationFile.getParentFile(), name);
                try {
                    Files.copy(selectedSourceFile.toPath(), destinationFile.toPath());
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }