我写了这篇日记,用户可以选择日期,为该日期写一些文字并保存。 文本存储在每个日期的哈希表中。
我现在正在尝试将哈希表保存在文件中。 关于我写的代码我几乎没有问题:
线程中的异常" main" 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总是警告我要为每个写一些处理文件的方法添加抛出。我认为这样做的方式是正确的吗?
是否像我一样将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);
}
}
答案 0 :(得分:0)
我没有收到任何警告,但ClassNotFoundException异常看起来没用。
避免对流使用静态变量。您可以在此特定代码中本地声明它们,但这不是规则。相反,你可以声明静态最终的日期,月份和年份,因为它们是常量而且永远不会改变。
这是您的选择,取决于代码最终的清晰程度。
请务必关闭蒸汽。
这是修改后的代码和我的建议。我暂时用java.util.Date替换了MyDate,所以我可以编译代码,你可以忽略它。
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 static final 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 static final String[] months = {"1","2","3","4","5","6","7","8","9","10","11","12"};
private static final String[] years = {"2014","2015","2016","2017","2018"};
private static final Font myFont = new Font("david", Font.BOLD, 24);
JButton btnSave, btnShow;
JComboBox daysBox,yearsBox,monthsBox;
private Hashtable<java.util.Date, String> diary;
private JTextArea textArea;
private File file;
//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<java.util.Date, 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());
java.util.Date date = new java.util.Date(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());
java.util.Date date = new java.util.Date(day, month, year);
String s = diary.get(date);
if (s!=null)
textArea.setText(s+" ");
else textArea.setText(" ");
}
}
}
@SuppressWarnings("unchecked")
private void updateHashFromFile() throws IOException, ClassNotFoundException{
if(!file.exists())
file.createNewFile();
else {
FileInputStream in = new FileInputStream(file);
ObjectInputStream streamIn = new ObjectInputStream(in);
diary = (Hashtable<java.util.Date, String>)streamIn.readObject();
streamIn.close();
}
}
//update the file with the new hash table diary data
private void updateHashToFile() throws IOException{
FileOutputStream out = new FileOutputStream(file);
ObjectOutputStream streamOut = new ObjectOutputStream(out);
streamOut.writeObject(diary);
streamOut.close();
}
}