使用带有从文件读取的项目列表的自定义 TableModel 时如何更新 jtable
How to update a jtable, when using a custom TableModel with a list of items read from a file
我的 Jtable/TableModel 有一个问题,无论我怎么努力,我似乎都无法解决。我正在开发一个地址簿程序,没有数据库程序,因为我们的教授希望我们手工学习所有内容,所以我拥有的是一个 .csv 文件,我用它来 read/write 联系人。我读取文件中的联系人,将它们放在一个列表中,使用该列表围绕它形成一个 TableModel,然后用所述 TableModel 创建一个 Jtable。我的问题出现了,当我在文件上写一个新的联系人时,jtable 不会用新信息更新自己,除非我关闭程序并重新启动它。我怎样才能使 table 使用新信息进行自我更新?
这里是我首先制作 jtable 和 table 模型的地方,不会 post 整个方法,因为它不相关。
List<Contatcs> listContacts = createListContacts(username);
tableModel = new TableModel(listContacts);
//create table, sorter and set single selection model
jTable = new JTable(tableModel);
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel);
JTableHeader jtHeader = jTable.getTableHeader();
这里是我创建联系人列表的地方
public static List<Contatcs> createListContacts(String username) throws FileNotFoundException{
String file = "CustomersAddressBooks\" + username + ".csv";
Scanner fileReader = new Scanner(new File(file));
List<Contatcs> retVal = new ArrayList();
while (fileReader.hasNextLine()){
String line = fileReader.nextLine();
line = line.replaceAll("\r||\n","");
String[] var = line.split(",");
if(!line.equals("") && !var[0].equals("FirstName") && !var[1].equals("LastName")){
retVal.add(new Contatcs(var[0],var[1],var[2],var[3],var[4],var[5],var[6],var[7],var[8]));
}
}
fileReader.close();
return retVal;
}
这是我的 TableModel class
public class TableModel extends AbstractTableModel {
private static final int COLUMN_FIRSTNAME = 0;
private static final int COLUMN_LASTNAME = 1;
private static final int COLUMN_PHONENUMBER = 2;
private static final int COLUMN_CITY = 3;
private String[] columnNames = {"First Name", "Last Name", "Phone Number", "City"};
private List<Contatcs> listContacts;
public TableModel(List<Contatcs> listContacts){
this.listContacts = listContacts;
int indexCount = 1;
for(Contatcs contact : listContacts){
contact.setIndex(indexCount++);
}
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return listContacts.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Contatcs contacts = listContacts.get(rowIndex);
Object retVal = null;
switch(columnIndex){
case COLUMN_FIRSTNAME: retVal = contacts.getFirstName(); break;
case COLUMN_LASTNAME: retVal = contacts.getLastName(); break;
case COLUMN_PHONENUMBER: retVal = contacts.getPhoneNumber(); break;
case COLUMN_CITY: retVal = contacts.getCity(); break;
default: throw new IllegalArgumentException("Invalid column index.");
}
return retVal;
}
@Override
public String getColumnName(int columnIndex){
return columnNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex){
if(listContacts.isEmpty()) return Object.class;
else return getValueAt(0,columnIndex).getClass();
}
}
这是谁做的小例子:
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel {
String[] column_name = new String[]{"Col1","Col2"};
Vector<String[]> list_value=new Vector<String[]>();
public TableModel() {
}
//add just one line the table
public void add_row(String[] row_values){
list_value.add(row_values);
}
//change the list
public void setList(Vector<String[]>list){
this.list_value=list;
}
@Override
public int getColumnCount() {
return column_name.length;
}
@Override
public int getRowCount() {
return list_value.size();
}
@Override
public Object getValueAt(int row, int col) {
return list_value.get(row)[col];
}
}
这是框架:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class MainFrame extends javax.swing.JFrame {
private JButton button1;
private JTextField val1;
private JTextField val2;
private JScrollPane scrollpanel;
private JButton button_replace;
private JTable table1;
public static void main(String[] args) {
MainFrame frame=new MainFrame();
frame.show();
}
public MainFrame() {
super();
//creating components
FlowLayout thisLayout = new FlowLayout();
getContentPane().setLayout(thisLayout);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
button1 = new JButton();
getContentPane().add(button1);
button1.setText("add");
button1.setPreferredSize(new java.awt.Dimension(81, 23));
val1 = new JTextField();
getContentPane().add(val1);
val1.setPreferredSize(new java.awt.Dimension(51, 23));
val2 = new JTextField();
getContentPane().add(val2);
val2.setPreferredSize(new java.awt.Dimension(53, 23));
pack();
setSize(400, 300);
//add the table now
scrollpanel = new JScrollPane();
scrollpanel.setPreferredSize(new java.awt.Dimension(339, 169));
getContentPane().add(scrollpanel);
table1 = new JTable();
scrollpanel.setViewportView(table1);
table1.setModel(new jtableExemple.TableModel());
TableModel table_model=(TableModel) table1.getModel();
table_model.add_row(new String[]{"row1","row1"});
table_model.add_row(new String[]{"row2","row2"});
table_model.add_row(new String[]{"row3","row3"});
button_replace = new JButton();
getContentPane().add(button_replace);
button_replace.setText("Replace all list");
//add action to button
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
TableModel table_model=(TableModel) table1.getModel();
table_model.add_row(new String[]{val1.getText(),val2.getText()});
//this line to the change in the UI
table1.setRowHeight(table1.getRowHeight());
}
});
button_replace.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
//create a random list
TableModel table_model=(TableModel) table1.getModel();
Vector<String[]>new_list=new Vector<String[]>();
for(int i=0;i<100;i++)
new_list.add(new String[]{"new row "+i,"new row "+i});
table_model.setList(new_list);
//this line to the change in the UI
table1.setRowHeight(table1.getRowHeight());
}
});
}
}
我的 Jtable/TableModel 有一个问题,无论我怎么努力,我似乎都无法解决。我正在开发一个地址簿程序,没有数据库程序,因为我们的教授希望我们手工学习所有内容,所以我拥有的是一个 .csv 文件,我用它来 read/write 联系人。我读取文件中的联系人,将它们放在一个列表中,使用该列表围绕它形成一个 TableModel,然后用所述 TableModel 创建一个 Jtable。我的问题出现了,当我在文件上写一个新的联系人时,jtable 不会用新信息更新自己,除非我关闭程序并重新启动它。我怎样才能使 table 使用新信息进行自我更新?
这里是我首先制作 jtable 和 table 模型的地方,不会 post 整个方法,因为它不相关。
List<Contatcs> listContacts = createListContacts(username);
tableModel = new TableModel(listContacts);
//create table, sorter and set single selection model
jTable = new JTable(tableModel);
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel);
JTableHeader jtHeader = jTable.getTableHeader();
这里是我创建联系人列表的地方
public static List<Contatcs> createListContacts(String username) throws FileNotFoundException{
String file = "CustomersAddressBooks\" + username + ".csv";
Scanner fileReader = new Scanner(new File(file));
List<Contatcs> retVal = new ArrayList();
while (fileReader.hasNextLine()){
String line = fileReader.nextLine();
line = line.replaceAll("\r||\n","");
String[] var = line.split(",");
if(!line.equals("") && !var[0].equals("FirstName") && !var[1].equals("LastName")){
retVal.add(new Contatcs(var[0],var[1],var[2],var[3],var[4],var[5],var[6],var[7],var[8]));
}
}
fileReader.close();
return retVal;
}
这是我的 TableModel class
public class TableModel extends AbstractTableModel {
private static final int COLUMN_FIRSTNAME = 0;
private static final int COLUMN_LASTNAME = 1;
private static final int COLUMN_PHONENUMBER = 2;
private static final int COLUMN_CITY = 3;
private String[] columnNames = {"First Name", "Last Name", "Phone Number", "City"};
private List<Contatcs> listContacts;
public TableModel(List<Contatcs> listContacts){
this.listContacts = listContacts;
int indexCount = 1;
for(Contatcs contact : listContacts){
contact.setIndex(indexCount++);
}
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return listContacts.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Contatcs contacts = listContacts.get(rowIndex);
Object retVal = null;
switch(columnIndex){
case COLUMN_FIRSTNAME: retVal = contacts.getFirstName(); break;
case COLUMN_LASTNAME: retVal = contacts.getLastName(); break;
case COLUMN_PHONENUMBER: retVal = contacts.getPhoneNumber(); break;
case COLUMN_CITY: retVal = contacts.getCity(); break;
default: throw new IllegalArgumentException("Invalid column index.");
}
return retVal;
}
@Override
public String getColumnName(int columnIndex){
return columnNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex){
if(listContacts.isEmpty()) return Object.class;
else return getValueAt(0,columnIndex).getClass();
}
}
这是谁做的小例子:
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel {
String[] column_name = new String[]{"Col1","Col2"};
Vector<String[]> list_value=new Vector<String[]>();
public TableModel() {
}
//add just one line the table
public void add_row(String[] row_values){
list_value.add(row_values);
}
//change the list
public void setList(Vector<String[]>list){
this.list_value=list;
}
@Override
public int getColumnCount() {
return column_name.length;
}
@Override
public int getRowCount() {
return list_value.size();
}
@Override
public Object getValueAt(int row, int col) {
return list_value.get(row)[col];
}
}
这是框架:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class MainFrame extends javax.swing.JFrame {
private JButton button1;
private JTextField val1;
private JTextField val2;
private JScrollPane scrollpanel;
private JButton button_replace;
private JTable table1;
public static void main(String[] args) {
MainFrame frame=new MainFrame();
frame.show();
}
public MainFrame() {
super();
//creating components
FlowLayout thisLayout = new FlowLayout();
getContentPane().setLayout(thisLayout);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
button1 = new JButton();
getContentPane().add(button1);
button1.setText("add");
button1.setPreferredSize(new java.awt.Dimension(81, 23));
val1 = new JTextField();
getContentPane().add(val1);
val1.setPreferredSize(new java.awt.Dimension(51, 23));
val2 = new JTextField();
getContentPane().add(val2);
val2.setPreferredSize(new java.awt.Dimension(53, 23));
pack();
setSize(400, 300);
//add the table now
scrollpanel = new JScrollPane();
scrollpanel.setPreferredSize(new java.awt.Dimension(339, 169));
getContentPane().add(scrollpanel);
table1 = new JTable();
scrollpanel.setViewportView(table1);
table1.setModel(new jtableExemple.TableModel());
TableModel table_model=(TableModel) table1.getModel();
table_model.add_row(new String[]{"row1","row1"});
table_model.add_row(new String[]{"row2","row2"});
table_model.add_row(new String[]{"row3","row3"});
button_replace = new JButton();
getContentPane().add(button_replace);
button_replace.setText("Replace all list");
//add action to button
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
TableModel table_model=(TableModel) table1.getModel();
table_model.add_row(new String[]{val1.getText(),val2.getText()});
//this line to the change in the UI
table1.setRowHeight(table1.getRowHeight());
}
});
button_replace.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
//create a random list
TableModel table_model=(TableModel) table1.getModel();
Vector<String[]>new_list=new Vector<String[]>();
for(int i=0;i<100;i++)
new_list.add(new String[]{"new row "+i,"new row "+i});
table_model.setList(new_list);
//this line to the change in the UI
table1.setRowHeight(table1.getRowHeight());
}
});
}
}