<Swing Dev> Is InputMap serializable or not?
Christopher Hegarty - Sun Microsystems Ireland
Christopher.Hegarty at Sun.COM
Wed Oct 22 08:11:03 UTC 2008
I think this observation is best directed to the
swing-dev at openjdk.java.net alias since the issue seems to be in
javax.swing.InputMap.
-Chris.
Paulo Levi wrote:
> Hi. I found that the component input map advertises itself as
> serializable, but it is really not, because somehow it seems to hold a
> reference to a not serializable ActionMap.
>
> A test case, sorry about the write/read functions, they were copied
> from a utility class (as you can see i had to replace the logging
> class):
>
>
> package ui;
>
> import java.io.BufferedInputStream;
> import java.io.BufferedOutputStream;
> import java.io.Closeable;
> import java.io.FileInputStream;
> import java.io.FileOutputStream;
> import java.io.ObjectInputStream;
> import java.io.ObjectOutputStream;
> import java.io.Serializable;
> import java.util.concurrent.Callable;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> import javax.swing.InputMap;
> import javax.swing.JTextPane;
> import javax.swing.KeyStroke;
> import static junit.framework.Assert.*;
> import org.junit.After;
> import org.junit.AfterClass;
> import org.junit.Before;
> import org.junit.BeforeClass;
> import org.junit.Test;
> import util.io.IoUtils;
>
>
> /**
> *
> * @author i30817
> */
> public class ApplicationTest {
>
> public ApplicationTest() {
> }
>
> @BeforeClass
> public static void setUpClass() throws Exception {
> }
>
> @AfterClass
> public static void tearDownClass() throws Exception {
> }
>
> @Before
> public void setUp() {
> }
>
> @After
> public void tearDown() {
> }
>
> /**
> * Test of read method, of class Application.
> */
> @Test
> public void testInputMapSerialization() {
> JTextPane editor = new JTextPane();
> InputMap map = editor.getInputMap();
> KeyStroke keystroke = KeyStroke.getKeyStroke("shift SPACE");
> map.put(keystroke, "test");
> writeObjects("InputMap", map);
> InputMap other = readObject("InputMap", new Callable(){
>
> public Object call() throws Exception {
> return new InputMap();
> }
>
> });
>
> assertEquals("test", other.get(keystroke));
>
> }
>
> /**
> * If possible reads an object, if not tries to instanciate the
> * object with the given Callable. This allows lazy instantiation.
> * This funtion can only read 1 object per file, to allow encapsulation
> * of the inputstreams.
> * If an exception occurs in the lazy instantiation it returns null.
> * Remember that if using Externalizable transient fields/static scopes
> * fields ARE initalized. The use of the default constructor assures that.
> * The order of inicialization is:
> * Externalizable : default constructor, readExternal
> * Serializable : first non-serializable super class default constructor,
> * readObject
> * So with externalizable you need to be carefull to replace the super state
> * and not to use it in the default constructor.
> * In serializable, you need to replace the constructor state.
> */
> @SuppressWarnings(value = "unchecked")
> public static <T> T readObject(String objectLocation, Callable t) {
> ObjectInputStream s = null;
> try {
> s = new ObjectInputStream(new BufferedInputStream(new
> FileInputStream(objectLocation)));
> return (T) s.readObject();
> } catch (Throwable ex) {
> Logger.getLogger(IoUtils.class.getName()).log(Level.WARNING,
> "Couldnt read object", ex);
> if (t != null) {
> try {
> return (T) t.call();
> } catch (Throwable e) {
>
> Logger.getLogger(ApplicationTest.class.getName()).log(Level.SEVERE,
> "Couldnt create object", e);
> }
> }
> } finally {
> close(s);
> }
> return null;
> }
>
> /**
> * If possible writes objects. Disallows null objects
> */
> public static void writeObjects(String objectLocation,
> Serializable... obj) {
> ObjectOutputStream s = null;
> try {
> s = new ObjectOutputStream(new BufferedOutputStream(new
> FileOutputStream(objectLocation)));
> for (Serializable a : obj) {
> if (a != null) {
> s.writeObject(a);
> }
> }
> s.flush();
> } catch (Throwable ex) {
> Logger.getLogger(ApplicationTest.class.getName()).log(Level.SEVERE,
> "Couldnt write object", ex);
> } finally {
> close(s);
> }
> }
>
> /**
> * Close closeables. Use this in a finally clause.
> */
> public static void close(Closeable... closeables) {
> for (Closeable c : closeables) {
> if (c != null) {
> try {
> c.close();
> } catch (Throwable ex) {
>
> Logger.getLogger(ApplicationTest.class.getName()).log(Level.WARNING,
> "Couldnt close Closeable", ex);
> }
> }
> }
> }
> }
More information about the swing-dev
mailing list