<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