Jython - 如何在 DefaultStyledDocument 中合并两个 LeafElements?
Jython - how can I merge two LeafElements in a DefaultStyledDocument?
我正在尝试 "normalise" DefaultStyledDocument 子类,在我们有 org.w3c.dom.Node.normalize()
的意义上:即合并相邻文本 "leaves"。在 DefaultStyledDocument 的情况下,如果两个相邻的叶子具有相同的属性(或 none),则这些叶子被识别为合并。
下面是一个简单版本(我们不检查实际属性:它是您拥有纯文本或具有一种可能标记样式的文本的用例)。
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 )
当我 运行 这个时,我得到这个错误:
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)
我赶紧补充一点,在尝试 javax.swing.text.DefaultStyledDocument()
作为 LeafElement 构造函数中的参数 1 之前,我尝试了“self
”(即在第一行调用 normalise
的 DefaultStyledDocument):同样的错误。
是的,可以做到:
AbstractDocument.BranchElement.replace()
看起来像这样:
public void replace(int offset, int length, Element[] elems)
...
原来这里的"offset"和"length"指的是BranchElement(通常是LeafElements)的sub-elements,而不是StyledDocument中底层文本的偏移量和长度。
比我聪明的人会更早得到这个。 API 文档 (Java 7) 可能会更清楚一点....
我正在尝试 "normalise" DefaultStyledDocument 子类,在我们有 org.w3c.dom.Node.normalize()
的意义上:即合并相邻文本 "leaves"。在 DefaultStyledDocument 的情况下,如果两个相邻的叶子具有相同的属性(或 none),则这些叶子被识别为合并。
下面是一个简单版本(我们不检查实际属性:它是您拥有纯文本或具有一种可能标记样式的文本的用例)。
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 )
当我 运行 这个时,我得到这个错误:
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)
我赶紧补充一点,在尝试 javax.swing.text.DefaultStyledDocument()
作为 LeafElement 构造函数中的参数 1 之前,我尝试了“self
”(即在第一行调用 normalise
的 DefaultStyledDocument):同样的错误。
是的,可以做到:
AbstractDocument.BranchElement.replace()
看起来像这样:
public void replace(int offset, int length, Element[] elems)
...
原来这里的"offset"和"length"指的是BranchElement(通常是LeafElements)的sub-elements,而不是StyledDocument中底层文本的偏移量和长度。
比我聪明的人会更早得到这个。 API 文档 (Java 7) 可能会更清楚一点....