简体   繁体   English

Jython-如何在DefaultStyledDocument中合并两个LeafElement?

[英]Jython - how can I merge two LeafElements in a DefaultStyledDocument?

I'm trying to "normalise" a DefaultStyledDocument subclass, in the sense that we have org.w3c.dom.Node.normalize() : that is, merge adjoining text "leaves". 在我们具有org.w3c.dom.Node.normalize()的意义上,我试图“标准化” DefaultStyledDocument子类:也就是说,合并相邻的文本“ leaves”。 In the case of a DefaultStyledDocument these leaves are identified for merging if two adjacent ones have the same attributes (or none). 对于DefaultStyledDocument,如果两个相邻的叶子具有相同的属性(或没有),则将这些叶子标识为合并。

Below is a simple version (we don't check the actual attributes: it is the use-case where you either have plain text, or text with one possible mark-up style). 下面是一个简单的版本(我们不检查实际属性:这是您使用纯文本或带有一种可能的标记样式的文本的用例)。

def normalise( self ):
    # recursive function:
    def normalise_structure( el, depth = 0 ):
        indent = '  ' * depth
        start = el.startOffset
        print( '%s# el %s |%s|' % ( indent, el, self.getText( start, el.endOffset - start )))
        prev_attr_set = None
        for i in range( el.elementCount ):
            subelement = el.getElement( i )
            normalise_structure( subelement, depth + 1 )
            if subelement.leaf:
                curr_attr_set = subelement.attributes
                print( '%s  # this is a leaf, attribs %s' % ( indent, curr_attr_set, ))
                # this is a simple version: only works if there is only one possible attribute
                if prev_attr_set and curr_attr_set and prev_attr_set.attributeCount == curr_attr_set.attributeCount:
                    print( '%s  # %s leaf needs to be merged with previous leaf' % ( 
                                indent, 'marked-up' if prev_attr_set.attributeCount == 1 else 'plain'))
                    attr_set = prev_attr_set.getElement( 0 ) if prev_attr_set.attributeCount else None
                    prev_subelement = el.getElement( i - 1 )
                    prev_start = prev_subelement.startOffset
                    curr_end = subelement.endOffset
                    merged_element = javax.swing.text.AbstractDocument.LeafElement( 
                        javax.swing.text.DefaultStyledDocument(), el, attr_set, prev_start, curr_end  )
                    el.replace( prev_start, curr_end - prev_start, [ merged_element ] )
                prev_attr_set = curr_attr_set
            else:
                print( '%s  # NOT a leaf...' % ( indent, ))
                prev_attr_set = None
    for self_el in self.rootElements:
        normalise_structure( self_el )

When I run this I get this error: 当我运行它时,我得到这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException at java.lang.System.arraycopy(Native Method) at javax.swing.text.AbstractDocument$BranchElement.replace(AbstractDocument.java:2290) 线程“ AWT-EventQueue-0”中的异常java.lang.System.arraycopy(本机方法)处的java.lang.ArrayIndexOutOfBoundsException javax.swing.text.AbstractDocument $ BranchElement.replace(AbstractDocument.java:2290)

I hasten to add that, before trying javax.swing.text.DefaultStyledDocument() as param 1 in the LeafElement constructor I tried " self " (ie the DefaultStyledDocument which invokes normalise on line one): same error. 我试图在将javax.swing.text.DefaultStyledDocument()用作LeafElement构造函数中的参数1之前尝试添加“ self ”(即在第一行调用normalise的DefaultStyledDocument)之前:相同的错误。

Yes, possible to do: 是的,可以这样做:

AbstractDocument.BranchElement.replace() looks like this: AbstractDocument.BranchElement.replace()看起来像这样:

public void replace(int offset, int length, Element[] elems)
  ...

Turns out that "offset" and "length" here refer to the sub-elements of the BranchElement (typically LeafElements), not to the offset and length of the underlying text in the StyledDocument. 事实证明,此处的“偏移”和“长度”是指BranchElement(通常为LeafElement)的子元素,而不是StyledDocument中基础文本的偏移和长度。

Somebody cleverer than me would have got this earlier. 比我聪明的人会早一点得到这个的。 API documentation (Java 7) might make it a bit clearer.... API文档(Java 7)可能会使它更加清晰。

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

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