我在表更新期间遇到了 initVectors 问题。它抛出一个 NullPointerException。
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at HardwareDbFile.HardwareInventoryUI.update(HardwareInventoryUI.java:47)
at java.util.Observable.notifyObservers(Observable.java:159)
at java.util.Observable.notifyObservers(Observable.java:115)
at HardwareDbFile.HardwareFileWatchdog.actionPerformed(HardwareFileWatchdog.java:36)
at javax.swing.Timer.fireActionPerformed(Timer.java:312)
at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
表模型
package HardwareDbFile;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
public class HardwareFileTableModel extends AbstractTableModel{
protected Vector data;
protected Vector columnNames ;
protected String datafile;
public HardwareFileTableModel(String file){
datafile = file;
initVectors();
}
public void initVectors() {
String aLine ;
data = new Vector();
columnNames = new Vector();
try {
FileInputStream fin = new FileInputStream(datafile);
try (BufferedReader br = new BufferedReader(new InputStreamReader(fin))) {
StringTokenizer st1 = new StringTokenizer(br.readLine(), "|");
while(st1.hasMoreTokens()) {
columnNames.addElement(st1.nextToken());
}
// extract data
while ((aLine = br.readLine()) != null) {
StringTokenizer st2 = new StringTokenizer(aLine, "|");
while(st2.hasMoreTokens()) {
data.addElement(st2.nextToken());
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int getRowCount() {
return data.size() / getColumnCount();
}
@Override
public int getColumnCount(){
return columnNames.size();
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = (String)columnNames.elementAt(columnIndex);
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex){
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return (String)data.elementAt( (rowIndex * getColumnCount()) + columnIndex);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
}
观察者类
package HardwareDbFile;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.Timer;
public class HardwareFileWatchdog extends Observable implements ActionListener {
Timer time = new Timer(1000,this); // check every second
long lastModified;
String file;
HardwareFileWatchdog (String string) {
file = string;
File f = new File(file);
lastModified = f.lastModified(); // original timestamp
time.start();
}
@Override
public void actionPerformed(ActionEvent e) {
File f = new File(file);
long actualLastModified = f.lastModified() ;
if (lastModified != actualLastModified) {
// the file have changed
lastModified = actualLastModified;
setChanged();
notifyObservers();
}
}
}
主类片段
public class HardwareInventoryUI extends javax.swing.JFrame implements Observer {
private String datafile = "hardware.dat";
private String dataFilePath = "C:\\Windows\\Temp\\hardware.dat";
protected HardwareFileTableModel model;
/**
* Creates new form HardwareInventoryUI
*/
public HardwareInventoryUI() {
initComponents();
HardwareFileWatchdog fileWD;
Font font;
font = new Font("SanSerif",Font.PLAIN,14);
setFont(font);
// this watchdog (an Observable object) is monitoring any file change
fileWD = new HardwareFileWatchdog(dataFilePath);
fileWD.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
// reload data because data file have changed
model.initVectors();
jTable.repaint();
}
添加记录的按钮操作
private void jAddRecordActionPerformed(java.awt.event.ActionEvent evt) {
String toolID = jToolID.getText();
String toolName = jToolName.getText();
String quantity = jQuantity.getText();
String itemPrice = jItemPrice.getText();
try {
FileWriter fstream = new FileWriter(dataFilePath, true);
BufferedWriter newRecord = new BufferedWriter(fstream);
newRecord.newLine();
newRecord.write(toolID + "|"+ toolName + "|" + quantity + "|" + itemPrice );
newRecord.close();
} catch (IOException ex) {
Logger.getLogger(HardwareInventoryUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
过程:在表模型中创建并加载文件,工作正常。当我尝试添加新记录时,问题就来了。记录以正确的格式添加到文本文件中,但在尝试使用新数据更新表模型期间会引发异常。我很茫然。