简体   繁体   English

Java swing组件序列化

[英]Java swing component serialization

I have to bugfix an old Java project. 我必须修正一个旧的Java项目。 This sticks to Java 5. It can be compiled with Java 8, but then some GUI components do no more work correctly. 坚持使用Java5。可以使用Java 8进行编译,但是随后某些GUI组件将无法正常工作。 The first thing i saw and really shocked me: This [censored] original developer had built a javax.swing package with many new classes, and many classes implemented again, which where already part of the standard library. 我看到的第一件事确实让我震惊:这个经过审查的原始开发人员构建了一个javax.swing包,其中包含许多新类,并且再次实现了许多类,而这些类已经成为标准库的一部分。 So the first thing i did was moving the whole crap to another namespace. 所以我要做的第一件事就是将整个废话移到另一个名称空间。 I used the Eclipse refactoring feature to rename the whole javax.swing and all its subpackages to somethingelse.swing. 我使用Eclipse重构功能将整个javax.swing及其所有子包重命名为somethingelse.swing。 Now it does not compile any more. 现在,它不再编译了。 Hopefully now i have the chance to find the bugs. 希望现在我有机会找到错误。

The current bug i'm stuck is in this method: 我卡住的当前错误是在此方法中:

private void writeObject(ObjectOutputStream s) throws IOException {
    s.defaultWriteObject();
    if (getUIClassID().equals(uiClassID)) {
        byte count = JComponent.getWriteObjCounter(this);
        JComponent.setWriteObjCounter(this, --count);
        if (count == 0 && ui != null) {
            ui.installUI(this);
        }
    }
}

The class this is part of is kind of a JComboBox with some extras. 该类的一部分是带有一些额外功能的JComboBox。 I do not really know what extras. 我真的不知道还有什么。 It's not important. 这并不重要。 The problem here is: The methods JComponent.getWriteObjCounter() and setWriteObjCounter() are package-private. 这里的问题是:方法JComponent.getWriteObjCounter()和setWriteObjCounter()是程序包专用的。 So the original code had access to these methods. 因此,原始代码可以访问这些方法。 The moved code now does not have. 现在没有移动的代码。 Since these are package-private, i did not find any documentation of it. 由于这些都是程序包专用的,因此我没有找到任何文档。 So i do not have an idea for what all this is, besides the fact that it is a custom serializer for the Java serialization feature. 因此,除了它是针对Java序列化功能的自定义序列化程序之外,我对此一无所知。

I do understand the first line. 我确实了解第一行。 That is standard. 那是标准。 Interestingly it only writes the default, it does not write anything else. 有趣的是,它只写默认值,不写其他任何东西。 So i strongly doubt if the whole method is necessary at all. 因此,我强烈怀疑整个方法是否完全必要。 But the remainder of the method i have no idea what it is supposed to do. 但是其余的方法我都不知道应该怎么做。 It seems to install the UI delegate if a counter is counted down to 0. But then, why on writing? 如果计数器的计数减为0,则似乎要安装UI委托。但是,为什么要写? Why not on reading? 为什么不读书呢? And what is this counter? 这个柜台是什么? How is it handled? 如何处理? For what purpose is it? 目的是什么?

The original Java code in the JComponent class here is: JComponent类中的原始Java代码如下:

static byte getWriteObjCounter(JComponent comp) {
    return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
}

But that does not shed much light to it either. 但这也没有给我们带来太多启示。 The attribute JComponent.flags is not accessible. 无法访问属性JComponent.flags。 Not from outside the javax.swing package. 不是从javax.swing包外部。 So again i have no idea what this is for. 所以我再次不知道这是干什么的。

As already said, i strongly doubt that this method makes any sense at all. 如前所述,我强烈怀疑这种方法是否有意义。 But if anyone could tell me for what purpose this writeObjCounter is i would have a chance for a better guess :) 但是,如果有人能告诉我这个writeObjCounter的目的是什么,我将有机会更好地猜测:)

Many thanks Siegfried Gipp 非常感谢Siegfried Gipp

Welcome in maintenance hell :-( 欢迎来到维护地狱:-(

Look in source of JComponent at constant WRITE_OBJ_COUNTER_FIRST : 在常量WRITE_OBJ_COUNTER_FIRSTJComponent源代码中WRITE_OBJ_COUNTER_FIRST

/** Bits 14-21 are used to handle nested writeObject calls. / **位14-21用于处理嵌套的writeObject调用。 **/ ** /
private static final int WRITE_OBJ_COUNTER_FIRST = 14; 私有静态最终int WRITE_OBJ_COUNTER_FIRST = 14;

Hence, the getWriteObjCounter(JComponent) and setWriteObjCounter(JComponent, byte) methods somehow handle the nesting depth when serializing nested JComponent objects. 因此,当序列化嵌套的JComponent对象时, getWriteObjCounter(JComponent)setWriteObjCounter(JComponent, byte)方法以某种方式处理嵌套深度。

Also look at the comment in front of these 2 methods : 还要看看这两种方法前面注释

// These functions must be static so that they can be called from //这些函数必须是静态的,以便可以从中调用它们
// subclasses inside the package, but whose inheritance hierarhcy includes //包内的子类,但其继承层次结构包括
// classes outside of the package below JComponent (eg, JTextArea). // JComponent下方的包之外的类(例如JTextArea)。

Therefore it is important these methods have default package access, or otherwise Swing serialization of subclasses of JComponent would not be compilable anymore. 因此,重要的是这些方法必须具有默认的程序包访问权限,否则,将无法再编译JComponent的子类的Swing序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM