0

Assignment:

I need to use a GUI interface to open a file, sum each line, and output the contents of each line followed by a series of spaces and the sum of each line to a new file. The new file must be labeled "Previousfilename"_out.txt aka *_out.txt if you will.

Where I'm at:

I have the GUI that works and copies the file.

It's editing and summing the lines in the file that seems to be an issue.

My current program with only the GUI working doesn't recognize new line characters and shows every int summed on a new line, e.g.,

input:

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

output:

1
3
6
10
15
20
26
30
33
42

Due to not needing the ',' separating the ints in my testfile.txt I removed the delimiter and the whole program fails after I hit copy with an error:

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)

How do I edit the copy even though its in use by the Jfilechooser? How can I get it to recognize new line characters but still print out the last sum with the EOF(had issues with a previous build that error-ed there.)?

Old Code: https://drive.google.com/open?id=1OOB5-21sJXQSl8XLlFPASaAPoIsXWnPu

New Code:

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


            }

        }
    }

This above is the GUI then my method of handling the process below

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________________ //about 2 hours after OP

ignore the override command in Jfilechooser it wasn't meant to be there. Also for new code its basically how do I get it do do what I want starting with what I know is working? Aka how can I get this to do what I need it to:

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 

    }
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Phatez
  • 111
  • 6
  • 1
    Simplify. You're trying to do too much at once and this is hampering your ability to debug, and what you should do is solve each problem in isolation. Your current problem is just reading in the file and parsing to int, nothing else, and so this and only this should be the code you try and the code you show. Right now it looks like you're trying to parse a complete line of numbers as if it were a single number, and that won't work. Read: [How to Debug Small Programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Hovercraft Full Of Eels Sep 29 '18 at 19:28
  • `I have 3 other assignments also due on Sunday night and a test Monday and Tuesday, so I need to get this done asap` - irrelevant to the question. We don't have time to read unnecessary information. If you want help you simplify the problem and the question. We all have time constraints. We answer question when we have time. In any case you need to learn to manage your time. We are not here to write code for you. – camickr Sep 29 '18 at 20:46
  • 1
    @Phatez I've removed a bunch of extraneous verbiage. Please only include relevant commentary and code in the future :) – Dave Newton Sep 29 '18 at 21:06

1 Answers1

1

I had a really long answer written out then my computer crashed.. let's see if we can do this again.

Any one of these concepts can be tough to understand for a beginner (GUI, files, etc). So here's a working solution from what I understood with your instructions. I tried not to change the overall structure too much from yours, so it would be more readable for you.

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

I made a few major changes, as well as many minor. Overall, you were close. Let me elaborate on the big changes.

  • First, I made fileSumCompute just implement the ActionListener interface. This way, you don't need to write a private inner class to handle actions. You can just use the .addActionListener(this) on whatever component you need.
  • Next, I reworked the actionPerformed() method. I split it into 3 parts, one for each button. I also changed how the variables were assigned. You looked like you had it pretty close, but there were some things off. From what I understand, you need to get a source file, read the source file in, sum each line in the source file, and write those sums to a new file with the same name as the source file with _out appended. If I misunderstood, I apologize.
  • Lastly, I changed the computeF method. Again, you were close. I changed it to use a simple method for reading a file in line by line, found on this site here. It reads each line in, splits each line with the split() method, then gets the int value for each number.

There were a lot of minor changes. Try to work through and understand them - this code isn't perfect, but reading working code is helpful in understanding concepts.

Additionally, I know Java and Object Oriented programming as a whole can be daunting. I recommend checking out the Oracle Docs for examples on concepts like GUI - they have some good examples on there. Lastly, don't try to learn these overnight. There is a lot to learn, so just take it one day at a time. Also, don't be afraid to check out this site for code snippets. There are a lot of good solutions here, such as the one I found.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
kennemat
  • 180
  • 2
  • 8
  • Thank you, I'm going to look over this real quick and then post any questions I have below. – Phatez Sep 29 '18 at 21:07
  • What does this signify? I like how you turned the lines into strings but what is textToWrite defined as? I don't see the string definition, and its initialized as "" is that standard in Java? textToWrite = ""; What does the System.getProperty("line.separator"); do? textToWrite+= sum + System.getProperty("line.separator"); I'm amazed how you cleaned up the Jfilechooser script and implemented it, I'll have to keep checking that script out for weeks to come to work out everything. -sorry saw the link to this portion after. – Phatez Sep 29 '18 at 21:20
  • I'm meant to copy the file and then add the sum at the end of the line for each line, but this being able to separate out lines and deal with the files, assuming it doesn't throw any errors saying the files are already in use with Jfilechooser, more then answers most if not all of my questions. I will try to play with this a little bit and see what I can and can't implement. Thank you! – Phatez Sep 29 '18 at 21:21
  • also it gets these errors when compiling, I wanted to see if it added to the end of the line or just computed the sum. fileSumCompute.java:113: error: constructor FileReader in class FileReader cannot be applied to given types; try (BufferedReader br = new BufferedReader(new FileReader(selectedDestinationFile.getAbsolutePath()))) { \FileReader.java:15: error: constructor FileReader in class FileReader cannot be applied to given types; try (BufferedReader reader = new BufferedReader(new FileReader(f))) { – Phatez Sep 29 '18 at 21:29
  • ok I added the java.io.FileReader in there to use the javas filereader, and now that the program compiles and runs I still end up with the same error I had before. : Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "1 2 3 4 5" .... with all the other stuff listed below – Phatez Sep 29 '18 at 21:54
  • Your code works if the java.io.FileReader is specified when defining BufferReader, and if you at a + in the sum = Integer.parseInt*, so it says the sum +=*. Now I need to edit it to get it to append these values to the end of a line. Thank you, this task is much more manageable so I'll say solved. I'm gonna save this page for offline use so I can look back at this. – Phatez Sep 29 '18 at 22:12