使用 Jfilechooser 编辑仍处于打开状态的文件副本,并在行尾附加 sum



赋值:

我需要使用 GUI 界面打开一个文件,对每一行求和,并将每行的内容后跟一系列空格和每行的总和输出到一个新文件中。新文件必须标记为"上一个文件名"_out.txt又名 *_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 
}

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

对于初学者来说,这些概念中的任何一个都很难理解(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);
}
}

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

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

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

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

最新更新