javax.swing.JTabbedPane 不可序列化?

标签 java swing serialization jtabbedpane

当我想要反序列化 JTabbedPane 时,我收到 NullPointerException。

我的代码如下:

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

public class Bee {

    public static void main(final String[] args) {

        // --------- create tabbed pane
        JTabbedPane tabbedPane = new JTabbedPane();

        // ------------ Test serializing -------------------
        final String file = "/tmp/swing.ser";
        FileOutputStream fout = null;
        ObjectOutputStream out = null;
        FileInputStream fin = null;
        ObjectInputStream oin = null;

        try {
        // ______________________ Write tabbedPane... _______________________
            fout = new FileOutputStream(file);
            out = new ObjectOutputStream(fout);

            out.writeObject(tabbedPane);

            out.close();

            // ____________________________reading pane___________________
            fin = new FileInputStream(file);
            oin = new ObjectInputStream(fin);

            final JTabbedPane readPane = (JTabbedPane) oin.readObject(); 
            System.out.println("readPane: " + readPane.toString());
            oin.close();
            fin.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        } catch (ClassNotFoundException e2) {
            e2.printStackTrace();
        }
    }
}

当我在 Ubuntu 20.04 上使用 OpenJDK 8 9、OpenJDK 11 或 Oracle JDK 14.0.1 以及 Win 10 上的 OpenJDK 9 和 Oracle JDK 14 运行此代码时(版本 1909),我得到以下或非常相似的堆栈跟踪(此处,我显示了 Ubuntu 20.04 上 Oracle JDK 14.0.1 的输出):

Exception in thread "main" java.lang.NullPointerException
at java.desktop/javax.swing.JTabbedPane.getTabCount(JTabbedPane.java:1118)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installTabContainer(BasicTabbedPaneUI.java:308)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installComponents(BasicTabbedPaneUI.java:304)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installUI(BasicTabbedPaneUI.java:248)
at java.desktop/javax.swing.JComponent.setUI(JComponent.java:685)
at java.desktop/javax.swing.JTabbedPane.setUI(JTabbedPane.java:253)
at java.desktop/javax.swing.JTabbedPane.updateUI(JTabbedPane.java:269)
at java.desktop/javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1363)
at java.desktop/javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1354)
at java.desktop/javax.swing.JComponent$ReadObjectCallback.validateObject(JComponent.java:5457)
at java.base/java.io.ObjectInputStream$ValidationList$1.run(ObjectInputStream.java:2758)
at java.base/java.io.ObjectInputStream$ValidationList$1.run(ObjectInputStream.java:2756)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
at java.base/java.io.ObjectInputStream$ValidationList.doCallbacks(ObjectInputStream.java:2754)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:506)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:457)
at Bee.main(Bee.java:31)

我知道,序列化 Swing 对象是一个坏主意。但是,我必须处理的代码大量使用了 Java Swing 的序列化功能。

因此,如果有人能指出我在反序列化 JTabbedPane 时所犯的错误,我将不胜感激。

更新: @GeorgeZ. 的评论让我研究了不同的 JDK 和操作系统:JDK 8 可以正常工作,在 Ubuntu 20.04 上没有 NullPointerException (OpenJDK 1.8.0_252 - 与我在原来的帖子中所写的相反)和 Win 10 build 1909 (OpenJDK 1.8.0_41)。 JDK 9 及更高版本 会产生 NullPointerException(在 Win10 上:OpenJDK 9 build 9+181 和 Oracle JDK 14.0.1;在 Ubuntu 20.04 上:OpenJDK 9 build 9+181、OpenJDK 11.0.7 和 Oracle JDK 14.0.1)。因此,这似乎是一种回归。

最佳答案

目前,JTabbedPane 无法在 JDK 9 及更高版本的 JDK 版本中反序列化,包括 JDK 15 的早期访问版本。

我提交了一份错误报告,您可以在 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8245785 找到该报告。 .

作为解决方法,您可以

  • 不序列化 Swing GUI 元素,而仅序列化重新创建 GUI 所需的数据模型(如 @DontKnowMuchBut_GettingBetter 指出的那样)或
  • 使用 JDK 8(感谢@GeorgeZ 的提示)。

关于javax.swing.JTabbedPane 不可序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61972888/

相关文章:

java - 如何使用 Apache Shiro 和 JSP 当用户重新登录时重定向到主页

java - 如何使 Controller 方法对 Spring 中的十六进制数敏感?

java - 对对象数组进行快速排序

java - 我们怎么不能将两个枚举值与 '<' 进行比较?

java - flamingo 是否支持从右到左的功能区菜单?

java - 在 Java JTree 上显示数据库中的数据

java - 多次使用 Box 变量

c++ - C/C++ : How to read a serialized graph (tree) from text file with tabulation?

c# - 无法将 JSON 数组反序列化为类型

java - 为什么双括号初始化要求 SerialVersionUID?