我一直在我编写的应用程序中使用JTextPane(或我的子类版本),所以我一直在使用Styles。我的程序没有按照我想要的方式运行,我跟踪了我认为是AttributeSet.containsAttributes(AttributeSet属性)方法中的错误的行为。我写了下面的简短程序来说明它:
import javax.swing.JTextPane;
import javax.swing.text.StyleConstants;
import javax.swing.text.Style;
public class StyleBug {
public static void main(String[] args) {
JTextPane textPane = new JTextPane();
textPane.setText("This is a test string");
Style bold = textPane.addStyle(BOLD, null);
StyleConstants.setBold(bold, true);
Style italic = textPane.addStyle(ITALIC, null);
StyleConstants.setItalic(italic, true);
int start = 5;
int end = 10;
textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(BOLD), false);
textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(ITALIC), false);
for(int i = start; i < end; i++)
System.out.println(textPane.getStyledDocument().getCharacterElement(i).getAttributes()
.containsAttributes(textPane.getStyle(BOLD))); //all print false
}
private static final String BOLD = "Bold";
private static final String ITALIC = "Italic";
}
这是一个错误,还是我在这里遗漏了什么?
答案 0 :(得分:4)
如果我注释掉这一行:
// textPane.getStyledDocument().setCharacterAttributes(start, end - start, textPane.getStyle(ITALIC), false);
然后它为所有元素打印为true。根据{{1}}的Javadoc,它使用了您传入的样式中的所有属性,因此您只需使用setCharacterAttributes
选项覆盖BOLD
选项。
编辑:
我调高了调试器并获得了ITALIC
的这一系列属性。
getCharacterElement(5)
如您所见,属性按2组进行排序。[0] javax.swing.text.StyleConstants$FontConstants "italic"
[1] java.lang.Boolean "true"
[2] javax.swing.text.StyleConstants "name"
[3] java.lang.String "Italic"
[4] javax.swing.text.StyleConstants$FontConstants "bold"
[5] java.lang.Boolean "true"
设置为true,italic
设置为true,bold
设置为{{1 }}。这可能意味着只允许一个名称用于字符的命名属性集。请注意,未命名的属性已正确合并,因此即使您无法查看特定的命名属性是否应用于角色,它仍然是您想要的行为。
答案 1 :(得分:2)
Bringer128发现了上述问题,但我稍后会澄清一点。
将样式添加到JTextPane时,作为参数传递的String实际上作为属性放置在样式中(不出所料,NameAttribute)。将样式应用于一系列字符时,NameAttribute将与在样式上设置的任何其他属性一起应用。因此,当应用我的BOLD样式时,该范围内的每个字符都将其BoldAttribute设置为true,并将其NameAttribute设置为“Bold”。然后,当应用我的ITALIC样式时,每个字符的ItalicAttribute都设置为true,然后将其NameAttribute设置为“Italic”。然后,当containsAttributes()检查我的BOLD样式中的所有属性是否都应用于这些字符时,它返回false,因为它们的NameAttributes已从“Bold”更改为“Italic”。我希望这不会让任何人感到困惑。
这是我的工作(我认为它实际上比原始代码更简单)。它的要点是我从不使用Styles或JTextPane.addStyle();我只是保持不变的MutableAttributeSets。
import javax.swing.JTextPane;
import javax.swing.text.StyleConstants;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
public class StyleBugFix {
public static void main(String[] args) {
JTextPane textPane = new JTextPane();
textPane.setText("This is a test string");
StyleConstants.setBold(BOLD, true);
StyleConstants.setItalic(ITALIC, true);
int start = 5;
int end = 10;
textPane.getStyledDocument().setCharacterAttributes(start, end - start, BOLD, false);
textPane.getStyledDocument().setCharacterAttributes(start, end - start, ITALIC, false);
for(int i = start; i < end; i++)
System.out.println(textPane.getStyledDocument().getCharacterElement(i).getAttributes()
.containsAttributes(BOLD)); //all now print true
}
private static final MutableAttributeSet BOLD = new SimpleAttributeSet();
private static final MutableAttributeSet ITALIC = new SimpleAttributeSet();
}
再次感谢Bringer128的帮助。