0

I'm making this grade keeping program for my computer science class and the one thing I haven't gotten to work is saving/loading sessions. As I have it set up now it automatically saves when you exit and loads when you start if there is a file to load. However, I feel I'm loading or saving it incorrectly; there's one main JFrame that holds all the data, and that's the one object that is saved. When it's loaded, well, it'd be easier to show you.

If it looks like this when I close it::

pre-save snapshot

Then it'll look like this when I start it up again:

post-load snapshot

Also, the "Enter Student" button, as well as the ActionListener on the JTextField used for input, cease to work when the program loads the JFrame. The program is split into 3 class files:

Gradebook:

import javax.swing.*;
import java.awt.event.*;
import java.io.*;

public class GradeBook implements java.io.Serializable {
    private static JFrame frame;
    public static void main(String[] args) throws Exception{
        try{
            FileInputStream fis = new FileInputStream("t.tmp");
            ObjectInputStream ois = new ObjectInputStream(fis);

            frame = (JFrame) ois.readObject();

            ois.close();
        } catch(Throwable t) {
            frame = new JFrame("Course Grades");
        }

        frame.addWindowListener(new closing());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new CourseGrade());
        frame.pack();
        frame.setVisible(true);
    }

closing:

    private static class closing extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            try {
                FileOutputStream fos = new FileOutputStream("t.tmp");
                ObjectOutputStream oos = new ObjectOutputStream(fos);

                oos.writeObject(frame);

                oos.close();
            } catch(Throwable t){System.out.println(t.getMessage());}
        }
    }
}

CourseGrade:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.FlowLayout;
import java.util.Random;
import javax.swing.table.*;
import java.io.*;
public class CourseGrade extends JPanel implements java.io.Serializable {
    private JLabel entername;
    private JTextField in;
    private JTextArea list;
    private JScrollPane scroll;
    private String[] students = new String[1000];
    private JButton enter;
    private JButton[] studentbuttons = new JButton[1000];
    private JButton[] delete=new JButton[1000];
    private int numstudents;
    private JFrame[] studentframes=new JFrame[1000];
    private static JTable[] tables=new JTable[1000];
    private static DefaultTableModel[] model=new DefaultTableModel[1000];
    private static int[] numass=new int[1000];
    public CourseGrade() {
        String[][] data = {{"", "", "", ""}};
        String[] headers = {"Assignment", "Date Assigned", "Score", "Percentage"};
        for(int i=0; i<tables.length; i++){
            model[i] = new DefaultTableModel(data, headers);
            tables[i] = new JTable(model[i]){
                public boolean isCellEditable(int rowIndex, int colIndex) {
                    return false;
                }
            };
        }
        numstudents=0;
        in=new JTextField(13);
        in.addActionListener(new enterListener());
        list=new JTextArea();
        scroll=new JScrollPane(list);
        list.setEditable(false);
        entername=new JLabel("Enter a student's name");
        enter=new JButton("Enter Student");
        enter.addActionListener(new enterListener());
        setPreferredSize(new Dimension(260, 300));
        setBackground(Color.green);

        add(entername);
        add(in);
        add(enter);
        add(scroll);

        scroll.setPreferredSize(new Dimension(240, 200));
    }

    private class enterListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            String x=in.getText();
            String y="";
            String z="";
            in.setText("");
            int a=numstudents+1;
            if(x.length()>0) x=a+". " + x + "\n";
            students[numstudents] = x;
            if(x.length()>0)numstudents++;
            for(int i=0; i<numstudents; i++){
                x=students[i];
                if(x.length()>13)x=x.substring(0,11)+"...\n";
                y+=x;
            }
            studentbuttons[numstudents]=new JButton("Edit");
            studentbuttons[numstudents].addActionListener(new grades());
            delete[numstudents]=new JButton("Delete");
            delete[numstudents].addActionListener(new del());
            list.setText(y);
            list.add(studentbuttons[numstudents]);
            studentbuttons[numstudents].setBounds(100,(numstudents-1)*16,55,15);
            list.add(delete[numstudents]);
            delete[numstudents].setBounds(160,(numstudents-1)*16,70,15);
        }
    }

    private class grades implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            Object obj = event.getSource();
            if(obj instanceof JButton){
                JButton clicked = (JButton)obj;
                int x=clicked.getY()/16;
                String y=students[x];
                for(int i=0; i<y.length(); i++){
                    String q=y.substring(i,i+1);
                    if(q.equals(" ")) { 
                        y=y.substring(i+1);
                        i=y.length()+1;
                    }
                }
                studentframes[x]=new JFrame(y+"'s Grades");
                studentframes[x].setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                try{studentframes[x].getContentPane().add(new GradePage(x, tables[x], numass[x]));}
                catch(Exception e){}
                studentframes[x].pack();
                studentframes[x].setVisible(true);
            }
        }
    }

    private class del implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            Object obj = event.getSource();
            if(obj instanceof JButton){
                JButton clicked = (JButton)obj;
                int x=clicked.getY()/16;
                String y="", z="";
                studentbuttons[numstudents].setVisible(false);
                delete[numstudents].setVisible(false);
                numstudents--;
                int q=3;
                int w=0;
                for(int i=x; i<=numstudents; i++){
                    if(i<10)q=1;
                    else if(i<100) q=2;
                    tables[i]=tables[i+1];
                    numass[i]=numass[i+1];
                    model[i]=model[i+1];
                    w=i+1;
                    try{if(!students[i+1].equals(null)){students[i]=w+students[i+1].substring(q);} else{students[i]=null;}}catch(Throwable t){}
                }
                for(int i=0; i<numstudents; i++){
                    y=students[i];
                    if(y.length()>13)y=y.substring(0,11)+"...\n";
                    z+=y;
                }
                list.setText(z);
            }
        }
    }
    public static void setTable(int numtable, JTable table){
        tables[numtable]=table;
    }
    public static void newRow(int numtable){
        model[numtable].addRow(new Object[]{"", "", "", ""});
    }
    public static void setNumEntries(int numtable, int num){
        numass[numtable]=num;
    }
}

The third class shouldn't have anything to do with this so I wont post it for now.

I realize the code is probably poorly written but I'm only in my second year of High School computer science and we haven't actually covered any of this. This program wasn't even supposed to be a GUI, and this is the first time I've even heard of Input or Output streams so I really don't know anything about them. I realize now that having the classes implement java.io.Serializable was probably unnecessary but when I was trying to research this I came across someone taking about how some objects can't be saved because they don't naturally implement it. So sorry if it's some stupid mistake, and thanks for your time.

Perception
  • 79,279
  • 19
  • 185
  • 195
Tim
  • 95
  • 3
  • 7
  • 4
    I would not be implementing `Serializable` for this type of functionality. Instead look to a host of other, less fragile methods of persisting settings and properties. E.G. as in [this answer](http://stackoverflow.com/a/7778332/418556) (which uses `Properties`). Java offers a 'bakers dozen' of ways to persist information. – Andrew Thompson Mar 04 '12 at 20:21
  • 1
    if the user updates his Java between serialization and deserialization there's a very good chance your approach will fail. – Oleg Mikheev Mar 04 '12 at 20:32

3 Answers3

1

You can store the data in a notepad file like this

            try
            {
                FileWriter file = new FileWriter( "insert file name here" );
                BufferedWriter buffer = new BufferedWriter( file ) ;
                buffer.write( "insert file content here" ) ;
                buffer.newLine();
                buffer.close();
            }
            catch ( IOException e )
            {
                //Insert error message here
            }

And then read it like this

    try
    {
        FileReader file = new FileReader( "insert file name here" ) ;

        BufferedReader buffer = new BufferedReader( file );

        String line = "" ;

        while( ( line = buffer.readLine() ) != null )
        {
            System.out.println( line ) ;
        }

        buffer.close() ;
    }
    catch( IOException e )
    {
        //Insert error message here
    }

Hope that helps

DalekCaan99
  • 51
  • 1
  • 8
0

i dont recomend that you save JFrame object. here is a better solution you can save the students name and there grades on a text file and each time your program loads it will load the information from the text file.

Hint : you can use Input & Output streams dirctly but it's maybe a little bit sonfusing so go and read about these two classes :

  1. Scanner (and how to use it to read from file)
  2. PrintWriter (and how to use it to write to file)

P.S.: i could'v given you the code but it is much better learning experience to suffer a little bit to find information, because while you are trying to figure it out you will learn a lot of other things.

0

The frame is not an integral part of your application's state, it's just a way of displaying the important information (names, grades, etc). If you want to save your session, save the information the is currently on the screen and then re-create the JFrame with the deserialized information. An ObjectOutputStream is a reasonable way of writing things to disk, and and ObjectInputStream is good for reading the data back in. The documentation contains good examples. Also, your classes would need to implement Serializable.

mbatchkarov
  • 15,487
  • 9
  • 60
  • 79
  • How can I read more than one instance of the same object? I have more than one JButton array that I would need to save/load, but if I use readObject, I don't know how to specify which of the two save arrays to load. – Tim Mar 05 '12 at 02:47