【发布时间】:2014-07-18 22:25:51
【问题描述】:
我写了这本日记,用户可以选择一个日期,为该日期写一些文本并保存它。 文本存储在每个日期的哈希表中。
我现在正在尝试将哈希表保存在文件中。 我对我写的代码有几个问题:
- 代码不工作,一些我不明白的错误:
线程“主”java.io.EOFException 中的异常
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Q2.MainPanel.updateHashFromFile(MainPanel.java:133)
at Q2.MainPanel.<init>(MainPanel.java:46)
at Q2.Main.main(Main.java:13)
eclipse 总是警告我在我编写的处理文件的每个方法中添加 throws。你认为我的做法对吗?
是像我一样将 FileInputStream、ObjectInputStream、File 声明为全局参数的好方法吗?还是有更多推荐的方法?
你认为像我一样在同一个类中编写面板和 GUI 处理以及数据和保存处理的好方法吗?还是将它们分成几个类会更好?
这是代码:
package Q2;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class MainPanel extends JPanel{
private String[] days = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
private String[] months = {"1","2","3","4","5","6","7","8","9","10","11","12"};
private String[] years = {"2014","2015","2016","2017","2018"};
private Font myFont = new Font("david", Font.BOLD, 24);
JButton btnSave, btnShow;
JComboBox daysBox,yearsBox,monthsBox;
private static Hashtable<MyDate, String> diary;
private JTextArea textArea;
private static File file;
private static FileInputStream in;
private static FileOutputStream out;
private static ObjectInputStream streamIn;
private static ObjectOutputStream streamOut;
//Constructor for main panel with BorderLayout with panels inside
public MainPanel () throws IOException, ClassNotFoundException{
this.setLayout(new BorderLayout());
add(getDateButtons(),BorderLayout.NORTH);
textArea = new JTextArea();
textArea.setFont(myFont);
add(textArea, BorderLayout.CENTER);
add(getSaveShowButtons(),BorderLayout.SOUTH);
file = new File("MyDiary");
updateHashFromFile();
diary = new Hashtable<MyDate, String>();
}
//create and return the NORTH date buttons panel
private JPanel getDateButtons(){
JPanel dateButtons = new JPanel();
//create and add the days JCombobox
daysBox = new JComboBox(days);
daysBox.setFont(myFont);
dateButtons.add(daysBox);
//create and add the months JCombobox
monthsBox = new JComboBox(months);
monthsBox.setFont(myFont);
dateButtons.add(monthsBox);
//create and add the year JCombobox
yearsBox = new JComboBox(years);
yearsBox.setFont(myFont);
dateButtons.add(yearsBox);
return dateButtons;
}
//
private JPanel getSaveShowButtons(){
JPanel saveShowButtons = new JPanel();
ButtonListener lis = new ButtonListener();
btnSave = new JButton("save");
btnSave.addActionListener(lis);
btnSave.setFont(myFont);
saveShowButtons.add(btnSave);
btnShow = new JButton("show");
btnShow.addActionListener(lis);
btnShow.setFont(myFont);
saveShowButtons.add(btnShow);
return saveShowButtons;
}
private class ButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==btnSave){
int day = Integer.parseInt((String)daysBox.getSelectedItem());
int month = Integer.parseInt((String)monthsBox.getSelectedItem());
int year = Integer.parseInt((String)yearsBox.getSelectedItem());
MyDate date = new MyDate(day, month, year);
System.out.println(date);
diary.put(date,textArea.getText());
textArea.setText(null);
try {
updateHashToFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
if (e.getSource()==btnShow){
int day = Integer.parseInt((String)daysBox.getSelectedItem());
int month = Integer.parseInt((String)monthsBox.getSelectedItem());
int year = Integer.parseInt((String)yearsBox.getSelectedItem());
MyDate date = new MyDate(day, month, year);
String s = diary.get(date);
if (s!=null)
textArea.setText(s+" ");
else textArea.setText(" ");
}
}
}
@SuppressWarnings("unchecked")
private static void updateHashFromFile() throws IOException, ClassNotFoundException{
if(!file.exists())
file.createNewFile();
else {
in = new FileInputStream(file);
streamIn = new ObjectInputStream(in);
diary = (Hashtable<MyDate, String>)streamIn.readObject();
}
}
//update the file with the new hash table diary data
private static void updateHashToFile() throws IOException{
out = new FileOutputStream(file);
streamOut = new ObjectOutputStream(out);
streamOut.writeObject(diary);
}
}
MyDate 类代码:
package Q2;
public class MyDate {
private static int[] numOfDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //Number of days on each month
private int day;
private int month;
private int year;
//Constructor for date object
public MyDate(int day, int month, int year){
if(day<=numOfDays[month-1]){ //In case chosen day that not exist in the month the last day of the month will be chosen
this.day = day;
}else this.day = numOfDays[month-1];
this.month = month;
this.year = year;
}
//@override toString
public String toString(){
return this.day+"/"+ this.month+"/"+this.year;
}
//@override equals
public boolean equals(Object other){
if(this.day==((MyDate)other).day && this.month==((MyDate)other).month && this.year==((MyDate)other).year)
return true;
return false;
}
public int hashCode() {
return ((day * 31) + month) * 31 + year;
}
}
主类代码:
package Q2;
import java.io.IOException;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException{
JFrame frame = new JFrame("Diary");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 700);
frame.setLocationRelativeTo(null);
MainPanel mainPanel = new MainPanel();
frame.add(mainPanel);
frame.setVisible(true);
}
}
【问题讨论】: