gpt4 book ai didi

java - 使用 TextFields 将学生的 ArrayList 存储在文件中

转载 作者:行者123 更新时间:2023-11-30 09:13:50 24 4
gpt4 key购买 nike

我制作了一个小型 java swing 应用程序来将学生列表存储在文件 students.txt 中。但是我在将许多学生保存到文件中时遇到了一个问题:当我点击“保存”按钮时,只有一个学生记录被存储。如果我在文本字段中输入新数据并再次单击保存按钮,它只会保存新创建的学生,覆盖旧记录,而我希望将新学生附加到文件中的现有学生列表。

这是我的代码:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class studentTest extends JFrame {

JPanel p1, p2, p3, p4, p5, p6;
JTextField f1, f2, f3, f4;
JLabel l1, l2, l3, l4;
JButton b1, b2, b3;

public studentTest() {
setBounds(100, 150, 300, 400);
b1 = new JButton("Save");
b1.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {

List<Student> Students = new ArrayList();
Student newStudents = new Student();
newStudents.setStudentFName(f1.getText());
newStudents.setStudentLName(f2.getText());
newStudents.setGPA(f4.getText());
newStudents.setID(f3.getText());
Students.add(newStudents);

try{

PrintWriter pw = new PrintWriter(new FileOutputStream("/Users/Yukki/Desktop/Students.txt"));
pw.println(newStudents+"\n");
pw.close();

} catch (FileNotFoundException ex) {

}

}

});
b2 = new JButton("First Record");
b3 = new JButton("Next");
l1 = new JLabel(" FirstName :");
l2 = new JLabel(" LastName :");
l3 = new JLabel(" ID :");
l4 = new JLabel(" GPA :");
f1 = new JTextField(10);
f2 = new JTextField(10);
f3 = new JTextField(10);
f4 = new JTextField(10);
p1 = new JPanel(new GridLayout(1, 2));
p1.add(l1);
p1.add(f1);
p2 = new JPanel(new GridLayout(1, 2));
p2.add(l2);
p2.add(f2);
p3 = new JPanel(new GridLayout(1, 2));
p3.add(l3);
p3.add(f3);
p4 = new JPanel(new GridLayout(1, 2));
p4.add(l4);
p4.add(f4);
p5 = new JPanel(new GridLayout(1, 1));
p5.add(b1);
p6 = new JPanel(new GridLayout(1, 2));
p6.add(b2);
p6.add(b3);
setLayout(new GridLayout(6, 1));
add(p1);
add(p2);
add(p3);
add(p4);
add(p5);
add(p6);
}

public static void main(String[] args) {
(new studentTest()).show();



}
}

最佳答案

虽然您可以尝试多种解决方案,但我还是推荐您。尝试使用 Java Architecture for XML Binding (JAXB) ,因为它将允许您定义将 Student 实例输出为 XML 的方式。

从那里,它应该允许您将多个实例添加到同一个文件。

可能会建议您序列化对象,但就我个人而言,我会避免这样做。它仅旨在用于对象的短期存储,通常用于通过电线传输,但这只是我的意见......

用例子更新...

这是基于 JAXB exmaple: Marshalling and Unmarshalling list or set of objects 中的示例和 JAXB Hello World Example

首先,我们需要定义Student 类和JAXB 注释。这使我们能够描述对象的实例应该如何编码(翻译)

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Student {

String name;
int age;
int id;

// This is a requirement of JAXB...
public Student() {
}

public Student(int id, String name, int age) {
this.name = name;
this.age = age;
this.id = id;
}

public String getName() {
return name;
}

@XmlElement
public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

@XmlElement
public void setAge(int age) {
this.age = age;
}

public int getId() {
return id;
}

@XmlAttribute
public void setId(int id) {
this.id = id;
}

}

接下来,我们需要创建一个可以包含对象列表的简单包装类。这是必需的,以便 JAXB API 可以更轻松地访问内部数据...

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType (XmlAccessType.FIELD)
@XmlRootElement
public class Students implements Iterable<Student> {

private List<Student> students;

public Students() {
this.students = new ArrayList<>(25);
}

public Student get(int index) {
return students.get(index);
}

public void add(Student student) {
students.add(student);
}

public void remove(Student student) {
students.remove(student);
}

public int size() {
return students.size();
}

@Override
public String toString() {
return "List-o-Students: " + size();
}

@Override
public Iterator<Student> iterator() {
return students.iterator();
}

}

然后,最后,我们需要对其进行测试......

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.jaxb.test.Student;
import org.jaxb.test.Students;

public class JAXBExample {

public static void main(String[] args) {

Students students = new Students();
students.add(new Student(100, "Bob", 29));
students.add(new Student(101, "John", 19));
students.add(new Student(102, "Joe", 39));
students.add(new Student(103, "Jane", 25));

try {

File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Students.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

jaxbMarshaller.marshal(students, file);
jaxbMarshaller.marshal(students, System.out);

} catch (JAXBException e) {
e.printStackTrace();
}
try {

File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Students.class);

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
students = (Students) jaxbUnmarshaller.unmarshal(file);
System.out.println(students);

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

}

}

哪些输出...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<students>
<students id="100">
<age>29</age>
<name>Bob</name>
</students>
<students id="101">
<age>19</age>
<name>John</name>
</students>
<students id="102">
<age>39</age>
<name>Joe</name>
</students>
<students id="103">
<age>25</age>
<name>Jane</name>
</students>
</students>
List-o-Students: 4

更新了可更新的示例

以下允许您动态更新 XML 超时。它与读、写、读的概念几乎相同,但提供了一些额外的功能......

try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File xml = new File("file.xml");
Document document = db.parse(xml);

// Create a new context...
JAXBContext jc = JAXBContext.newInstance(Students.class);

// Create a new Binder from the context
Binder<Node> binder = jc.createBinder();
// Load the document
Students students = (Students) binder.unmarshal(document);

// Update the student at position 0
Student student = students.get(0);
student.setAge(100);

// Add a new student
students.add(new Student(200, "Harry", 65));

// Update the document
binder.updateXML(students);

// Write the contents back to the file..
FileOutputStream fos = null;
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
fos = new FileOutputStream(xml);
t.transform(new DOMSource(document), new StreamResult(fos));
} catch (TransformerFactoryConfigurationError | TransformerException exp) {
exp.printStackTrace();
} finally {
try {
fos.close();
} catch (Exception e) {
}
}
} catch (ParserConfigurationException | SAXException | IOException | JAXBException exp) {
exp.printStackTrace();
}

这可能看起来有点复杂,但这意味着您现在可以动态修改基础文档。

虽然为了您的需要,我会简单地在开始时读取现有列表,更新列表,最后,当您准备好时,将其写回...但只有我...

最后,一个完全可运行的示例...

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.jaxb.test.Student;
import org.jaxb.test.Students;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class JAXBExample {

public static void main(String[] args) {

Students students = new Students();
students.add(new Student(100, "Bob", 29));
students.add(new Student(101, "John", 19));
students.add(new Student(102, "Joe", 39));
students.add(new Student(103, "Jane", 25));

write(students);
students = null;
students = read();

for (Student student : students) {
System.out.println(student);
}

update();

students = null;
students = read();

for (Student student : students) {
System.out.println(student);
}

}

public static void write(Students students) {

System.out.println("----> Write");
try {

File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Students.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

jaxbMarshaller.marshal(students, file);
// jaxbMarshaller.marshal(students, System.out);

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

}

public static Students read() {

System.out.println("----< Read");
Students students = null;
try {

File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Students.class);

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
students = (Students) jaxbUnmarshaller.unmarshal(file);
System.out.println(students);

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

return students;

}

public static void update() {

System.out.println("----> Update");
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File xml = new File("file.xml");
Document document = db.parse(xml);

JAXBContext jc = JAXBContext.newInstance(Students.class);

Binder<Node> binder = jc.createBinder();
Students students = (Students) binder.unmarshal(document);

Student student = students.get(0);
student.setAge(100);

students.add(new Student(200, "Harry", 65));

binder.updateXML(students);

FileOutputStream fos = null;
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
fos = new FileOutputStream(xml);
t.transform(new DOMSource(document), new StreamResult(fos));
} catch (TransformerFactoryConfigurationError | TransformerException exp) {
exp.printStackTrace();
} finally {
try {
fos.close();
} catch (Exception e) {
}
}
} catch (ParserConfigurationException | SAXException | IOException | JAXBException exp) {
exp.printStackTrace();
}
}

}

关于java - 使用 TextFields 将学生的 ArrayList 存储在文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20829001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com