【问题标题】:Using Jfilechooser edit a file copy that is still open with appending sum at the end of the line使用 Jfilechooser 编辑仍然打开的文件副本,并在行尾附加 sum
【发布时间】:2018-09-29 19:23:46
【问题描述】:

作业:

我需要使用 GUI 界面打开一个文件,对每一行求和,然后将每行的内容后跟一系列空格和每行的总和输出到一个新文件。如果愿意,新文件必须标记为“Previousfilename”_out.txt aka *_out.txt。

我在哪里:

我有可以工作并复制文件的 GUI。

它正在编辑和汇总文件中似乎有问题的行。

我当前只有 GUI 工作的程序无法识别换行符,并显示每个 int 总和在一个新行上,例如,

输入:

1, 2, 3, 4, 5
5, 6
4, 3, 9

输出:

1
3
6
10
15
20
26
30
33
42

由于不需要 ',' 分隔 testfile.txt 中的整数,我删除了分隔符,并且在我点击复制并出现错误后整个程序失败:

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "1 2 3 4 5"
        at java.lang.NumberFormatException.forInputString(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at java.lang.Integer.parseInt(Unknown Source)
        at fileSumCompute.computeF(fileSumCompute.java:210)
        at fileSumCompute$myHandler.actionPerformed(fileSumCompute.java:105)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
        at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
        at java.awt.Component.processMouseEvent(Unknown Source)
        at javax.swing.JComponent.processMouseEvent(Unknown Source)
        at java.awt.Component.processEvent(Unknown Source)
        at java.awt.Container.processEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Window.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$500(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

即使 Jfilechooser 正在使用该副本,我如何编辑它?我怎样才能让它识别换行符,但仍然用 EOF 打印出最后一个总和(以前的构建有问题,在那里出错。)?

旧代码: https://drive.google.com/open?id=1OOB5-21sJXQSl8XLlFPASaAPoIsXWnPu

新代码:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.nio.file.*;
import java.util.*;

public class fileSumCompute extends JFrame{
//my first gui
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)  
    {
        fileSumCompute cpy1 = new fileSumCompute();
        cpy1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cpy1.setSize(600, 150);
        cpy1.setVisible(true);
    }
    //my first time creating and opening files without direct command line input. 

    public fileSumCompute() {  @Override
        //peiced together a couple JfileChooser examples and customized... I cant seem to get it to work without the other path selection and preprograming it into the same directory as source file. 
        //It works though.
        super("Compute sum of row. New file = \" *_out.txt\" ");
        setLayout(new GridLayout(3, 3, 5, 5));
        fc = new JFileChooser();

        //Open dialog box to make easier to find files
        workingDirectory = new File(System.getProperty("user.dir"));
        fc.setCurrentDirectory(workingDirectory);

     //create labels and buttons
        chooseFileButton = new JButton("CHOOSE SOURCE FILE");
        destinationButton = new JButton("DESTINATION FOLDER");
        copyButton = new JButton("COMPUTE & SAVE FILE");      //copies file so origonal is preserved
        sourceLabel = new JLabel("SOURCE: ");
        sourceText = new JTextField(10);
        sourceText.setEditable(false);
        destinationLabel = new JLabel("DESTINATION: ");
        destinationText = new JTextField(10);
        destinationText.setEditable(false);

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

        //Create myHandler object to add action listeners for the buttons.
        myHandler handler = new myHandler(); //handles the files and copies them 
        chooseFileButton.addActionListener(handler);
        destinationButton.addActionListener(handler);
        copyButton.addActionListener(handler);
        //computeF(name);
    }

    //Inner class to create action listeners    
    private class myHandler implements ActionListener {
        private File selectedSourceFile;
        private File selectedDestinationFile;

        public void actionPerformed(ActionEvent event) 
        {
            int returnVal;
            String selectedFilePath;
            File selectedFile;


            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());

                    //where we implement the second file... here is where we'll call to compute the sum of the lines 
                    String name = selectedSourceFile.getName();
                    name = selectedSourceFile.getName().substring(0, name.lastIndexOf(".")) + "_out.txt"; //changed the output file to read ("Orig name here"_out.txt)
                    File destinationFile = new File(selectedDestinationFile.getParentFile(), name); 
                    //destinationFile.deleteOnExit();

                    try {
                        Files.copy(selectedSourceFile.toPath(), destinationFile.toPath()); //copying and computing
                        computeF(destinationFile); //if we can get this to edit the _out.txt file we can do with out creating two seperate files- the previous *_.tmp can just be the *_out.txt
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }

                }
            }


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

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


            }

        }
    }

以上是图形用户界面 然后是我处理下面过程的方法

public static void computeF(File selectedDestinationFile) throws IOException{
        //int i=0;
        if (!selectedDestinationFile.isFile()) // IF CANNOT FIND FILE
        {
            System.out.println("File.txt - Parameter is not an existing file");
            return;
        }

        Scanner fileReader = null; //using the namespace for readability.
        int lineSum=0;
        try
        {
            fileReader = new Scanner(selectedDestinationFile);
        }
        catch (IOException a) //it insists on a try catch
        {
            a.printStackTrace();
        }

        String name = selectedDestinationFile.getName();
        System.setOut(new PrintStream(new FileOutputStream(name)));
        while(fileReader.hasNext()) { 
                    String number = fileReader.next();
                    sum += Integer.parseInt(number);
                    System.out.println(sum);

                    if(fileReader.hasNextLine()) {
                        System.out.println(sum);
                        sum = 0;
                    }
                }


    }
}


/*_______________________________________________________________________________________________________________________*/
                          /*implement after Working script*/
//is there a way to append instead of doing the System.setout? like with this similarly found code.
/* appending how can I implement this??
try(FileWriter fw = new FileWriter("myfile.txt", true);
    BufferedWriter bw = new BufferedWriter(fw);
    PrintWriter out = new PrintWriter(bw))
{
    out.println("the text");
    //more code
    out.println("more text");
    //more code
} catch (IOException e) {
    //exception handling left as an exercise for the reader
}

// or this one? I need to keep the copy but just add to the end so that makes the most sense.  

fout = new FileWriter("filename.txt", true);

*/
/*______________________________________________________________________________________________________________________*/

_________________edit________________ //手术后约 2 小时

忽略 Jfilechooser 中的覆盖命令,它不应该在那里。 同样对于新代码,它基本上如何让它做我想做的事情,从我知道的工作开始?也就是我怎样才能让它做我需要它做的事情:

public static void computeF(FILE in)
    {   

        if (!selectedDestinationFile.isFile()) // IF CANNOT FIND FILE
        {
            System.out.println("File.txt - Parameter is not an existing file");
            return;
        }
        Scanner fileReader = null; //using the namespace for readability.
        try
        {
            fileReader = new Scanner(in);
        }
        catch (IOException a) //it insists on a try catch
        {
            a.printStackTrace();
        }
        String name = in.getName();
        fout = new FileWriter(name, true);// to try to append to the copy instead of rewriting the whole file 

    }

【问题讨论】:

  • 简化。你试图一次做太多事情,这会妨碍你的调试能力,你应该做的是孤立地解决每个问题。您当前的问题只是读取文件并解析为 int,仅此而已,因此只有这应该是您尝试的代码和显示的代码。现在看起来你正试图解析一整行数字,就好像它是一个数字一样,这是行不通的。阅读:How to Debug Small Programs
  • I have 3 other assignments also due on Sunday night and a test Monday and Tuesday, so I need to get this done asap - 与问题无关。我们没有时间阅读不必要的信息。如果你想帮助你简化问题和问题。我们都有时间限制。有时间的时候回答问题。无论如何,你需要学会管理你的时间。我们不是来为你写代码的。
  • @Phatez 我已经删除了一堆无关紧要的措辞。以后请只包含相关的注释和代码:)

标签: java file-io filereader jfilechooser file-writing


【解决方案1】:

我写了一个很长的答案然后我的电脑崩溃了..让我们看看我们是否可以再次这样做。

对于初学者来说,这些概念中的任何一个都很难理解(GUI、文件等)。因此,根据我对您的说明的理解,这是一个可行的解决方案。我尽量不要对你的整体结构做太多改动,这样对你来说更具可读性。

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class fileSumCompute extends JFrame implements ActionListener {

    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;
    private File selectedSourceFile = null;
    private File selectedDestinationFolder;
    private static String textToWrite;
    // my first time creating and opening files without direct command line input.

    public fileSumCompute() {
        // peiced together a couple JfileChooser examples and customized... I cant seem
        // to get it to work without the other path selection and preprograming it into
        // the same directory as source file.
        // It works though.
        super("Compute sum of row. New file = \" *_out.txt\" ");
        setLayout(new GridLayout(3, 3, 5, 5));
        fc = new JFileChooser();

        // Open dialog box to make easier to find files
        workingDirectory = new File(System.getProperty("user.dir"));
        fc.setCurrentDirectory(workingDirectory);

        // create labels and buttons
        chooseFileButton = new JButton("CHOOSE SOURCE FILE");
        destinationButton = new JButton("DESTINATION FOLDER");
        copyButton = new JButton("COMPUTE & SAVE FILE"); // copies file so origonal is preserved
        sourceLabel = new JLabel("SOURCE: ");
        sourceText = new JTextField(10);
        sourceText.setEditable(false);
        destinationLabel = new JLabel("DESTINATION: ");
        destinationText = new JTextField(10);
        destinationText.setEditable(false);

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

        // Add this as action listener.
        chooseFileButton.addActionListener(this);
        destinationButton.addActionListener(this);
        copyButton.addActionListener(this);
        // computeF(name);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        Object event = arg0.getSource();
        int returnVal;

        if (event == chooseFileButton) {
            returnVal = fc.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                selectedSourceFile = fc.getSelectedFile();
                sourceText.setText(selectedSourceFile.getName());
            }
        } else if (event == destinationButton) {
            fc.setCurrentDirectory(new java.io.File("."));
            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                selectedDestinationFolder = fc.getSelectedFile();
                destinationText.setText(selectedDestinationFolder.getName());
            }
        } else if (event == copyButton) {
            // where we implement the second file... here is where we'll call to compute the
            // sum of the lines
            String name = selectedSourceFile.getName();
            // changed the output file to read ("Orig name here"_out.txt)
            name = selectedSourceFile.getName().substring(0, name.lastIndexOf(".")) + "_out.txt";
            File destinationFile = new File(selectedDestinationFolder, name);

            try {
                //Files.copy(selectedSourceFile.toPath(), destinationFileFolder.toPath()); // copying and computing
                computeF(selectedSourceFile); // if we can get this to edit the _out.txt file we
                // can do with out creating two seperate files- the previous *_.tmp can just be
                // the *_out.txt
                PrintWriter writer = new PrintWriter(destinationFile, "UTF-8");
                writer.println(textToWrite);
                writer.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void computeF(File selectedDestinationFile) throws IOException {
        textToWrite = ""; 
        int sum;
        if (!selectedDestinationFile.isFile()) // IF CANNOT FIND FILE
        {
            System.out.println(selectedDestinationFile.getAbsolutePath() + " - Parameter is not an existing file");
            return;
        }

        try (BufferedReader br = new BufferedReader(new FileReader(selectedDestinationFile.getAbsolutePath()))) {
            String line;
            while ((line = br.readLine()) != null) {
                //Split each line, then check value in the array as an int and add to sum.
               String[] temp = line.split(", ");
               sum = 0;

               for (int i = 0; i < temp.length; i++) 
                   sum = Integer.parseInt(temp[i]); 

               textToWrite+= sum + System.getProperty("line.separator");
            }
        }

    }

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

我做了一些大的改动,也做了很多小的改动。总的来说,你很接近。让我详细说明一下重大变化。

  • 首先,我让fileSumCompute 实现了ActionListener 接口。这样,您无需编写私有内部类来处理操作。您可以在任何您需要的组件上使用.addActionListener(this)
  • 接下来,我重新设计了actionPerformed() 方法。我将它分成 3 个部分,每个按钮一个。我还更改了变量的分配方式。你看起来已经很接近了,但有些事情不对劲。据我了解,您需要获取一个源文件,读入源文件,对源文件中的每一行求和,然后将这些总和写入一个与源文件同名并附加 _out 的新文件。如果我误解了,我深表歉意。
  • 最后,我更改了computeF 方法。再一次,你很亲密。我将其更改为使用一种简单的方法逐行读取文件,可在此站点here 上找到。它读取每一行,使用split() 方法分割每一行,然后获取每个数字的 int 值。

有很多细微的变化。尝试完成并理解它们——这段代码并不完美,但阅读工作代码有助于理解概念。

此外,我知道 Java 和面向对象编程作为一个整体可能令人生畏。我建议查看 Oracle 文档以获取有关 GUI 等概念的示例 - 他们有一些很好的示例。最后,不要试图在一夜之间学会这些。有很多东西要学,所以一天一次地学习。此外,不要害怕查看此站点以获取代码 sn-ps。这里有很多很好的解决方案,比如我找到的那个。

【讨论】:

  • 谢谢,我会快速查看一下,然后在下面发布我的任何问题。
  • 这意味着什么?我喜欢你如何将这些行变成字符串,但 textToWrite 定义为什么?我没有看到字符串定义,它初始化为“”是Java中的标准吗? textToWrite = ""; System.getProperty("line.separator"); 是什么?做? textToWrite+= sum + System.getProperty("line.separator");我很惊讶您如何清理 Jfilechooser 脚本并实现它,我将不得不继续检查该脚本数周才能解决所有问题。 - 抱歉之后看到了这部分的链接。
  • 我的意思是复制文件,然后在每行的行尾添加总和,但这能够分离行并处理文件,假设它没有抛出任何错误,说明文件已与 Jfilechooser 一起使用,然后回答我的大部分问题(如果不是全部)。我会试着玩一点,看看我能实现什么,不能实现什么。谢谢!
  • 在编译时也会出现这些错误,我想看看它是添加到行尾还是只是计算总和。 fileSumCompute.java:113:错误:类 FileReader 中的构造函数 FileReader 不能应用于给定类型; try (BufferedReader br = new BufferedReader(new FileReader(selectedDestinationFile.getAbsolutePath()))) { \FileReader.java:15: 错误:类 FileReader 中的构造函数 FileReader 不能应用于给定类型;尝试 (BufferedReader reader = new BufferedReader(new FileReader(f))) {
  • 好的,我在其中添加了 java.io.FileReader 以使用 javas 文件读取器,现在程序编译并运行,我仍然遇到与以前相同的错误。 :线程“AWT-EventQueue-0”中的异常 java.lang.NumberFormatException:对于输入字符串:“1 2 3 4 5” .... 以及下面列出的所有其他内容
猜你喜欢
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多