Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations sizbut on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to save and restore listener info?

Status
Not open for further replies.

GDameron

Programmer
Aug 8, 2003
39
US
Using JDK 1.4. New to Java.

I have been playing with saving a JPanel and its contents to a file using writeObject, then restoring it with readObject. However, when the JPanel is read back and displayed, I'm finding that any action listeners I had set up are not being restored. Is this because listeners are not serializable, and so are not savable?

If so, is there a way to save and restore listener info?
 
I think listeners are savable but this does not make sence to save a listener. There also exists other objects whaat does not make sence to save, for example streams, sockets, they are not savable and does not make sence to save them.

Ion Filipski
1c.bmp
 
If you need to save the listeners, you can customize the serializer by overriding readObject and writeObject. This will get you started:

class MyPanel extends JPanel {
private void writeObject(ObjectOutputStream oos) throws IOException {
System.out.println("writeObject");
oos.defaultWriteObject();
ContainerListener[] cls = (ContainerListener[])(getListeners(ContainerListener.class));
oos.writeObject(Arrays.asList(cls));
}
private void readObject(ObjectInputStream ios) throws IOException, ClassNotFoundException {
try {
ios.defaultReadObject();
java.util.List list = (java.util.List)ios.readObject();
System.out.println("listeners: "+list);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Sean McEligot
 
Sean - I tried implementing your suggestion, but at the line:

oos.defaultWriteObject();

I get this:

java.io.NotActiveException: not in call to writeObject

I'm pretty new to Java - could it have something to do with the fact that the overridden writeObject() is expecting an ObjectOutputStream argument, whereas the standard expects an Object?

Or maybe I'm not invoking it right? (What would a proper invocation of your writeObject() look like?)
 
could it have something to do with the fact that the overridden writeObject() is expecting an ObjectOutputStream argument, whereas the standard expects an Object?

That is for ObjectOutputStream itself, not for the Serializable objects. Read the documentation for ObjectOutputStream for more info. There a chapter on object serialization included with the JDK documentation.

try invoking it like this:

FileOutputStream fos = new FileOutputStream("panel.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myJPanel);
fos.close();

FileInputStream fis = new FileInputStream("panel.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Component c = (Component)ois.readObject();,
fis.close();

Also. don't forget to implement Serializable in all your Listeners, or you will get a NotSerializableException.



Sean McEligot
 
Okay. I've corrected the invocation, which got me past the NotActiveException. But now, as you anticipated, I am getting a NotSerializableException. Oddly, it's occurring on the

oos.defaultWriteObject();

line, even if that's the only line in the overridden writeObject(). So now I'm confused -- I wasn't getting this exception when I was using the "standard" writeObject(). Isn't xxx.defaultWriteObject (inside of an overridden writeObject()) equivalent to the "standard" writeObject()?

In any event, you recommended that I "implement Serializable in all your Listeners". Lots of reading and experimenting later, a solution eludes me. Because listeners are interfaces (not classes), any attempt to "implement Serializable" on them gives a compile error. I tried creating a new class that extends ActionListener and implements Serializable, but I haven't been able to get the syntax right (compile errors).

I'm stuck. I'm hoping it's a greenhorn mistake. Any help, code snippets, or links are appreciated.
 
you should not serialize lisetners because it does not make sence. You should load them only at runtime. So, if you do not want to get different kind of errors, you should mark them as transient. And if you have marked listeners as implement Serializable then remove it. Again, listeners, events, sockets, pipes, streams and many other kind of objects does not make sence to be serializable. In a class which implements Serializable you must mark them as transient.

Ion Filipski
1c.bmp
 
Ion may be right. If you can, it is better to add your Listeners after deserializing. There are cases where you might want to serialize your Listeners. For example, if Listeners are added dynamically based on user commands.

Here's how to create you serializable action listeners if you choose to.

abstract class MyActionListener implements ActionListener, Serializable {
}

button.addActionListener(new MyActionListener() {
public void actionPerformed(ActionEvent e) {
...
}});

Also, the NotSerializableException should tell you the class name that caused the problem.

Sean McEligot
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top