如何在文件发生变化时将扩展 AbstractTableModel 的 class 保存到文件中?
How to save a class that extends AbstractTableModel into a file whenever it changes?
我有两个 class。第一个classmainWindow extends JFrame
里面有一个JTabletable1。
在我的第二个 class 中,我需要得到这个 table。当我在主窗口中生成 getter 时,我需要执行 mainWindow win = new mainWindow();
才能跟随 win.getTable1();
。问题是 mainWindow win = new mainWindow();
的东西打开了 window,所以我最后得到了两次。如何从第二个 class 中获取对 table1 的引用?
mainWindow.java
package windows;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import helpers.*;
public class mainWindow extends JFrame {
private final String fileName = "Studenten";
public studentTableModel model;
private JPanel rootPanel;
private JComboBox comboBox1;
private JTable table1;
private JButton generierenButton;
private calculations calc = new calculations();
public mainWindow() throws IOException {
super("Zufallsgenerator fürs Repetieren");
pack();
setContentPane(rootPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000, 700);
List<student> studentList = calc.readFromFile("Studenten");
model = new studentTableModel(studentList);
table1.setModel(model);
setVisible(true);
}
}
studentTableModel.java
package helpers;
import windows.mainWindow;
import javax.swing.table.AbstractTableModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class studentTableModel extends AbstractTableModel {
private calculations calc = new calculations();
private final List<student> students;
private final String[] columnNames = new String[] {
"Id", "Name", "Bereits x-Mal repetiert", "Wahrscheinlichkeit", "im Pot"
};
private final Class[] columnClass = new Class[] {
String.class, String.class, int.class, double.class, Boolean.class
};
public studentTableModel(List<student> students){
this.students = students;
}
@Override
public String getColumnName(int column){
return columnNames[column];
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
return columnClass[columnIndex];
}
@Override
public int getColumnCount()
{
return columnNames.length;
}
@Override
public int getRowCount()
{
return students.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
student row = students.get(rowIndex);
if(0 == columnIndex) {
return row.getId();
}
else if(1 == columnIndex) {
return row.getName();
}
else if(2 == columnIndex) {
return row.getAnzahlRepetitonen();
}
else if(3 == columnIndex) {
return row.getWahrscheinlichkeit();
}
else if(4 == columnIndex) {
return row.isInPot();
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return true;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
{
student row = students.get(rowIndex);
if(0 == columnIndex) {
row.setId((String) aValue);
}
else if(1 == columnIndex) {
row.setName((String) aValue);
}
else if(2 == columnIndex) {
row.setAnzahlRepetitonen((Integer) aValue);
}
else if(3 == columnIndex) {
row.setWahrscheinlichkeit((Double) aValue);
}
else if(4 == columnIndex) {
row.setInPot((Boolean) aValue);
}
List<student> students1 = new ArrayList<student>();
//here I need to get the table data to save it to a file using the method in the next class
calc.saveToFile("newStudents", students1);
}
}
calculations.java
package helpers;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class calculations {
public void saveToFile(String file,List<student> studentList){
int length = studentList.size();
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
} catch (IOException e) {
e.printStackTrace();
return;
}
for (helpers.student student : studentList){
String id = student.getId();
String name = student.getName();
int rep = student.getAnzahlRepetitonen();
double wahrscheinlichkeit = student.getWahrscheinlichkeit();
boolean inPot = student.isInPot();
try {
fileWriter.write(id + ";" + name + ";" + Integer.toString(rep) + ";" + Double.toString(wahrscheinlichkeit) + ";" + Boolean.toString(inPot) + "\n");
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public List<student>readFromFile(String file){
List<student> studentList = new ArrayList<student>();
String line = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
try {
while ((line = br.readLine()) != null){
student st = null;
String[] cols = line.split(";");
String id = cols[0];
String name = cols[1];
int rep = Integer.parseInt(cols[2]);
double wahrscheinlichkeit = Double.parseDouble(cols[3]);
boolean isPot = Boolean.parseBoolean(cols[4]);
st = new student(id, name,rep, wahrscheinlichkeit, isPot);
studentList.add(st);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return studentList;
}
public List<student> getTableData(JTable table, List<student> studentList){
int rows = table.getModel().getRowCount();
for (int i = 0; rows >= i;){
String id = (String) table.getModel().getValueAt(i, 0);
String name = (String) table.getModel().getValueAt(i, 1);
int anzahl = (int) table.getModel().getValueAt(i, 2);
double prob = (Double) table.getModel().getValueAt(i, 3);
boolean inPot = (Boolean) table.getModel().getValueAt(i, 4);
studentList.add(new student(id, name, anzahl, prob, inPot));
System.out.println("Read row " + i);
}
return studentList;
}
}
changeListener
table1.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
System.out.println("Change detected");
List<student> newStudentList = new ArrayList<student>();
calc.getTableData(table1, newStudentList);
System.out.println("Now saving...");
calc.saveToFile("newStudents", newStudentList);
}
});
the program should have printed "Change detected" once there was a change in the table, but nothing happened.
确实 addTableModelListener
...
[...] Adds a listener to the list that's notified each time a change to the data model occurs.
但是通过扩展摘要 class AbstractTableModel
,您有责任使用提供的方法(例如 fireTableDataChanged()
引起此类通知)。何时执行取决于您,但方法 setValueAt
看起来是通知侦听器的好地方,因为它是更改 table 数据的方法。
我有两个 class。第一个classmainWindow extends JFrame
里面有一个JTabletable1。
在我的第二个 class 中,我需要得到这个 table。当我在主窗口中生成 getter 时,我需要执行 mainWindow win = new mainWindow();
才能跟随 win.getTable1();
。问题是 mainWindow win = new mainWindow();
的东西打开了 window,所以我最后得到了两次。如何从第二个 class 中获取对 table1 的引用?
mainWindow.java
package windows;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import helpers.*;
public class mainWindow extends JFrame {
private final String fileName = "Studenten";
public studentTableModel model;
private JPanel rootPanel;
private JComboBox comboBox1;
private JTable table1;
private JButton generierenButton;
private calculations calc = new calculations();
public mainWindow() throws IOException {
super("Zufallsgenerator fürs Repetieren");
pack();
setContentPane(rootPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000, 700);
List<student> studentList = calc.readFromFile("Studenten");
model = new studentTableModel(studentList);
table1.setModel(model);
setVisible(true);
}
}
studentTableModel.java
package helpers;
import windows.mainWindow;
import javax.swing.table.AbstractTableModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class studentTableModel extends AbstractTableModel {
private calculations calc = new calculations();
private final List<student> students;
private final String[] columnNames = new String[] {
"Id", "Name", "Bereits x-Mal repetiert", "Wahrscheinlichkeit", "im Pot"
};
private final Class[] columnClass = new Class[] {
String.class, String.class, int.class, double.class, Boolean.class
};
public studentTableModel(List<student> students){
this.students = students;
}
@Override
public String getColumnName(int column){
return columnNames[column];
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
return columnClass[columnIndex];
}
@Override
public int getColumnCount()
{
return columnNames.length;
}
@Override
public int getRowCount()
{
return students.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
student row = students.get(rowIndex);
if(0 == columnIndex) {
return row.getId();
}
else if(1 == columnIndex) {
return row.getName();
}
else if(2 == columnIndex) {
return row.getAnzahlRepetitonen();
}
else if(3 == columnIndex) {
return row.getWahrscheinlichkeit();
}
else if(4 == columnIndex) {
return row.isInPot();
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return true;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
{
student row = students.get(rowIndex);
if(0 == columnIndex) {
row.setId((String) aValue);
}
else if(1 == columnIndex) {
row.setName((String) aValue);
}
else if(2 == columnIndex) {
row.setAnzahlRepetitonen((Integer) aValue);
}
else if(3 == columnIndex) {
row.setWahrscheinlichkeit((Double) aValue);
}
else if(4 == columnIndex) {
row.setInPot((Boolean) aValue);
}
List<student> students1 = new ArrayList<student>();
//here I need to get the table data to save it to a file using the method in the next class
calc.saveToFile("newStudents", students1);
}
}
calculations.java
package helpers;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class calculations {
public void saveToFile(String file,List<student> studentList){
int length = studentList.size();
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
} catch (IOException e) {
e.printStackTrace();
return;
}
for (helpers.student student : studentList){
String id = student.getId();
String name = student.getName();
int rep = student.getAnzahlRepetitonen();
double wahrscheinlichkeit = student.getWahrscheinlichkeit();
boolean inPot = student.isInPot();
try {
fileWriter.write(id + ";" + name + ";" + Integer.toString(rep) + ";" + Double.toString(wahrscheinlichkeit) + ";" + Boolean.toString(inPot) + "\n");
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public List<student>readFromFile(String file){
List<student> studentList = new ArrayList<student>();
String line = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
try {
while ((line = br.readLine()) != null){
student st = null;
String[] cols = line.split(";");
String id = cols[0];
String name = cols[1];
int rep = Integer.parseInt(cols[2]);
double wahrscheinlichkeit = Double.parseDouble(cols[3]);
boolean isPot = Boolean.parseBoolean(cols[4]);
st = new student(id, name,rep, wahrscheinlichkeit, isPot);
studentList.add(st);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return studentList;
}
public List<student> getTableData(JTable table, List<student> studentList){
int rows = table.getModel().getRowCount();
for (int i = 0; rows >= i;){
String id = (String) table.getModel().getValueAt(i, 0);
String name = (String) table.getModel().getValueAt(i, 1);
int anzahl = (int) table.getModel().getValueAt(i, 2);
double prob = (Double) table.getModel().getValueAt(i, 3);
boolean inPot = (Boolean) table.getModel().getValueAt(i, 4);
studentList.add(new student(id, name, anzahl, prob, inPot));
System.out.println("Read row " + i);
}
return studentList;
}
}
changeListener
table1.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
System.out.println("Change detected");
List<student> newStudentList = new ArrayList<student>();
calc.getTableData(table1, newStudentList);
System.out.println("Now saving...");
calc.saveToFile("newStudents", newStudentList);
}
});
the program should have printed "Change detected" once there was a change in the table, but nothing happened.
确实 addTableModelListener
...
[...] Adds a listener to the list that's notified each time a change to the data model occurs.
但是通过扩展摘要 class AbstractTableModel
,您有责任使用提供的方法(例如 fireTableDataChanged()
引起此类通知)。何时执行取决于您,但方法 setValueAt
看起来是通知侦听器的好地方,因为它是更改 table 数据的方法。