Java - JFrame 保存多行

标签 java csv jframe save

过去几个小时我一直在用头撞墙,试图让我的程序运行,但没有成功。

我正在开发一个基于 JFrame 的简单程序,该程序应该打开窗口,让我输入变量,然后如果我按“保存”,则将它们保存到选定的 .csv 文件中。

然而,当我尝试保存 2 组或更多组变量时,问题就出现了,第一组总是被覆盖,并且只有新的变量存在。

例如代替:

马克,100,2, 约翰, 50, 1

在文件中我只找到

约翰福音 50, 1

我猜这与每次单击“保存”按钮时创建新的 bufferedwriter 有关,但我不知道如何绕过这样做,我尝试了放置它的多个位置,但它永远不会起作用,因为我得到如果它在 Action 方法之外,则会出错。

代码如下:

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

/**
 * Demonstrates etc
 */
public class Homework1 extends JFrame implements ActionListener {

   JTextField jtfName1;
   JTextField jtfName2;
   JTextField jtfName3;
   JTextField jtfName4;

   static File file = new File("121Lab1.csv"); 

   public Homework1() {
        // Set BorderLayout with horizontal gap 5 and vertical gap 10
      setLayout(new BorderLayout(10, 10));


        // Create a JPanel with FlowLayout for the South of the JFrame's BorderLayout

      JPanel jpSouth = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 3));

        // Create some buttons to place in the south area
      JButton jbCalc = new JButton("Calculate");
      JButton jbSave = new JButton("Save");
      JButton jbClear = new JButton("Clear");
      JButton jbExit = new JButton("Exit");

      jpSouth.add(jbCalc);
      jpSouth.add(jbSave);
      jpSouth.add(jbClear);
      jpSouth.add(jbExit);

      jbCalc.addActionListener(this);
      jbSave.addActionListener(this);
      jbClear.addActionListener(this);
      jbExit.addActionListener(this);


        // Place the south panel in the JFrame's south area
      add(jpSouth, BorderLayout.SOUTH);

        // Add textfields to the rest of the frame

      JPanel jpCenter = new JPanel(new GridLayout(0,2));

      jpCenter.add(new JLabel("Item name: ", SwingConstants.RIGHT));
      jtfName1 = new JTextField("", 10);
      jpCenter.add(jtfName1);
      jtfName1.addActionListener(this);

      jpCenter.add(new JLabel("Number of: ", SwingConstants.RIGHT));
      jtfName2 = new JTextField("", 10);
      jpCenter.add(jtfName2);
      jtfName2.addActionListener(this);

      jpCenter.add(new JLabel("Cost: ", SwingConstants.RIGHT));
      jtfName3 = new JTextField("", 10);
      jpCenter.add(jtfName3);
      jtfName3.addActionListener(this);

      jpCenter.add(new JLabel("Amount owed: ", SwingConstants.RIGHT));
      jtfName4 = new JTextField("", 10);
      jpCenter.add(jtfName4);
      jtfName4.addActionListener(this);

      add(jpCenter, BorderLayout.CENTER);

   }

   public void actionPerformed(ActionEvent ae) {
      String actionString = ae.getActionCommand(); // gets the string on the component
      Object actionObj = ae.getSource();


      if (actionString.equalsIgnoreCase("Calculate")) { // ae.getSource() == jbCancel
         System.out.println("You clicked Calculate");
         try {
            double value = Double.parseDouble(jtfName2.getText())*Double.parseDouble(jtfName3.getText());
            jtfName4.setText(String.format("%.2f", value));
         } 
         catch (NumberFormatException nfe) {
            jtfName4.setText("Not a number");
         }

      } 
      else if (actionString.equalsIgnoreCase("Save")) { 

         try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(jtfName1.getText()+",");
            writer.write(jtfName2.getText()+",");
            writer.write(jtfName3.getText()+"\r\n");
            writer.flush();
            writer.close();
         } 
         catch(IOException e) {
            System.out.println("IO Error");
         }         
      } 
      else if (actionString.equalsIgnoreCase("Clear")) { 

         System.out.println("You clicked Clear");
         jtfName1.setText("");
         jtfName2.setText("");
         jtfName3.setText("");
         jtfName4.setText("");

      } 
      else if (actionString.equalsIgnoreCase("Exit")) { 


         setVisible(false);
         dispose();


      } 
      else {
         System.out.println("Unknown command: " + actionString);
         System.out.println("Unknown source:  " + actionObj);
      }
   } 




   public static void main(String[] args) throws IOException {

      Homework1 jfMain = new Homework1();
      jfMain.setTitle("Item Order Calculator");
      jfMain.setSize(450, 200);
      jfMain.setLocationRelativeTo(null);       // Center JFrame
      jfMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      jfMain.setVisible(true);


   } // end main
} // end class JPanelTester

最佳答案

每次单击保存时,文件及其内容都会被覆盖。您需要告诉 FileWriter 您希望附加到文件末尾,例如...

BufferedWriter writer = new BufferedWriter(new FileWriter(file), true);

参见FileWriter(File, boolean)了解更多详情

BufferedWriter还有一个newLine方法,可以向文件写入新行...

writer.write(jtfName1.getText()+",");
writer.write(jtfName2.getText()+",");
writer.write(jtfName3.getText());
writer.newLine();

您也没有很好地管理您的资源。如果你打开一个资源,你应该尽一切努力关闭它,否则你可能会遇到资源泄漏和其他奇怪的问题

幸运的是,在 Java 7+ 中,管理这些类型的资源非常容易

    try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
        writer.write(jtfName1.getText()+",");
        writer.write(jtfName2.getText()+",");
        writer.write(jtfName3.getText());
        writer.newLine();
     } 
     catch(IOException e) {
        System.out.println("IO Error");
     }       

参见The try-with-resources Statement了解更多详情

关于Java - JFrame 保存多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28224265/

相关文章:

java - 显示快速查找数组

python - 如何根据匹配数据从 csv 中删除行

java - 将可编辑文本框添加到 JFrame

java - 让函数返回 JLabel 并将其添加到 JFrame

java - Play : Is it possible to extract form data without binding it to a model?

java - java中的帧边界

java - 如何在现有背景图像上添加侧边菜单(导航菜单)

flutter - 如何使用 Flutter 从 FaceBook 导出数据到 CSV 文件

python - 如何在 Scikit 中从 CSV 执行朴素贝叶斯分类

java - (JFrame) 如何读取随机数以用不同的方法进行比较而不显示它?