我制作了一个类来保存comboxbox的内容并加载它们。我使用ObjectOutput并直接保存模型。问题是,我得到一个例外:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: javax.swing.SpringLayout


我真的不明白为什么会这样,因为我没有在任何代码中的任何地方(我可以告诉我)使用SpringLayout。我什至在stream.writeOutput(getModel());上设置了一个断点,并且getModel()肯定会返回DefaultComboboxModel,所以再也没有提到Spring Layout。

然后,我编译从(here)获得示例的代码,它可以正常工作。为什么会这样呢?

class MemComboBox extends JComboBox
{
    public static final int MAX_MEM_LEN = 30;

    public MemComboBox()
    {
        super();
        setEditable(true);
    }

    public void add(String item)
    {
        removeItem(item);
        insertItemAt(item, 0);
        setSelectedItem(item);
        if (getItemCount() > MAX_MEM_LEN)
            removeItemAt(getItemCount() - 1);
    }

    public void load(String fName)
    {
        try
        {
            if (getItemCount() > 0)
                removeAllItems();
            File f = new File(fName);
            if (!f.exists())
                return;
            FileInputStream fStream = new FileInputStream(f);
            ObjectInput stream = new ObjectInputStream(fStream);

            Object obj = stream.readObject();
            if (obj instanceof ComboBoxModel)
                setModel((ComboBoxModel) obj);

            stream.close();
            fStream.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void save(String fName)
    {
        try
        {
            FileOutputStream fStream = new FileOutputStream(fName);
            ObjectOutput stream = new ObjectOutputStream(fStream);
            Object object = getModel();
            stream.writeObject(object);

            stream.flush();
            stream.close();
            fStream.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


我在这里创建实例:

    languageList = new MemComboBox();
    languageList.setBounds(146, 167, 166, 22);
    languageList.load(ClientInfo.GetAppData() + "/languages.xml");
    languageList.addActionListener(comboboxAdded);
    getContentPane().add(languageList);


这是堆栈跟踪:

java.io.NotSerializableException: javax.swing.SpringLayout
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at javax.swing.event.EventListenerList.writeObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at org.CCInc.Psyc.Windows.NewClient$MemComboBox.save(NewClient.java:688)
    at org.CCInc.Psyc.Windows.NewClient$7.windowClosing(NewClient.java:540)
    at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
    at java.awt.Window.processWindowEvent(Unknown Source)
    at javax.swing.JDialog.processWindowEvent(Unknown Source)
    at java.awt.Window.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

最佳答案

没有更多的代码,我无法确定,但是...

堆栈跟踪中的at org.CCInc.Psyc.Windows.NewClient$MemComboBox.save(NewClient.java:688)行表示MemComboBox类是NewClient类的内部类。如果不是静态内部类,则序列化将尝试写出整个“ NewClient”对象。这是因为在每个非静态内部类中都有对外部类的引用。

10-06 02:36