Java 在JTextPane中获取所选文本的属性
我试图找出如何在JTextPane中获取所选文本的属性。 我发现最好的解决方案是使用getInputAttribute()和CaretListener。但是我对这个实现有一些问题 我的解决方案显示插入符号最后位置上的文本属性,但不显示插入符号的实际位置。我做错了什么?求你了 这是我的SSCCE:Java 在JTextPane中获取所选文本的属性,java,attributes,selection,jtextpane,caret,Java,Attributes,Selection,Jtextpane,Caret,我试图找出如何在JTextPane中获取所选文本的属性。 我发现最好的解决方案是使用getInputAttribute()和CaretListener。但是我对这个实现有一些问题 我的解决方案显示插入符号最后位置上的文本属性,但不显示插入符号的实际位置。我做错了什么?求你了 这是我的SSCCE: public class Testovani{ static JTextPane pane; static JLabel label; public static void main(String[
public class Testovani{
static JTextPane pane;
static JLabel label;
public static void main(String[] args) throws BadLocationException {
JFrame frame = new JFrame();
frame.setSize(350, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
pane = new JTextPane();
label = new JLabel();
pane.addCaretListener(new SelectionListener());
MutableAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setBold(attrs, true);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is first row non bold", null);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is second row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
pane.getDocument().insertString(0, "This is third row bold", attrs);
pane.getDocument().insertString(0, "\n", null);
frame.add(pane);
frame.add(label, BorderLayout.SOUTH);
frame.setVisible(true);
}
private static class SelectionListener implements CaretListener{
@Override
public void caretUpdate(CaretEvent e) {
AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();
label.setText("Is bold: " + String.valueOf(StyleConstants.isBold(attrs)));
}
}}
我有两个额外的问题。这种方法是用于选择还是仅用于插入符号的位置?如果有一部分为粗体而第二部分为非粗体的文本选择,结果会是什么?实际上,选择的属性是一个复杂的问题,需要您了解业务需求 假设选择了一段文本,您需要选择字体大小。但是 片段有3段不同大小的文本 选择开始位置位于10pt文本的中间,然后是一段12pt大小的文本,选择结束于14pt大小片段的中间 你想要多大尺寸的?10、12、14或(多个) 最简单的方法是使用InputAttribute 默认情况下,属性是从插入符号位置复制的,但您当然可以添加插入符号侦听器,并在每次更新时根据业务逻辑(处理具有不同属性的多个文本片段)检查和填充输入属性 更新:
尝试包装
属性集attrs=((StyledEditorKit)窗格.getEditorKit()).getInputAttribute()
在SwingUtilities.invokeLater()调用中,没有获取选择属性的预期行为,这仅仅是因为选择可以具有每个不同属性的字符元素
您必须了解,返回文本窗格为下一次输入计算出的最佳属性的getInputAttributes
与返回当前插入符号位置属性的getCharacterAttributes
之间存在差异。对于选择,插入符号是结束选择的位置。如果从左到右或从右到左选择文本,它可以是给定的getSelectionStart
或getSelectionEnd
无论如何,我建议您获取JTextPane的StyledDocument,然后从getSelectionStart
到getSelectionEnd
迭代字符元素:
for(int i=jtp.getSelectionStart(); i<jtp.getSelectionEnd(); i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
for(int i=jtp.getSelectionStart();i我使用@Sharcoux的解决方案,但做了一个更改:我确保始终至少有一个字符需要迭代。当没有选择时,getSelectionStart()==getSelectionEnd()
。出于这个原因,我将对以下内容做一点小小的更改:
int iStart = jtp.getSelectionStart();
int iEnd = jtp.getSelectionEnd();
if(iStart > 0) iStart--;
else if(iEnd < jtp.getDocument().getEndPosition().getOffset()) iEnd++;
for(int i = iStart; i < iEnd; i++) {
AttributeSet set = jtp.getStyledDocument().getCharacterElement(i).getAttributes();
//here, combine, analyse, do whatever you like with your AttributeSet
//You can use StyleConstants.xxx to analyse the attributes
}
int-iStart=jtp.getSelectionStart();
int iEnd=jtp.getSelectionEnd();
如果(iStart>0)iStart--;
else if(iEnd
唯一一个不改变任何内容的例子是当文档完全为空时,在这种情况下,getInputAttribute
应该可以正常工作。肯定是有用的答案,我稍后会使用它。但首先,我需要知道为什么方法getInputAttribute()在my CaretListener中,返回上一个插入符号位置的属性。这是因为这通常是预期的行为:如果您将插入符号放在粗体文本之后,您通常也希望您的输入是粗体的。非常感谢。它很有效。StanislavL中的更新答案解决了我的问题。谢谢,我已经为选定的插入符号使用了此选项但是,如果没有选择,它在某些特殊情况下无法正常工作。如果没有选择,我需要用于文本的属性,将写入什么。我希望,这是方法getInputAttribute()的返回看起来是。但它给了我最后一个插入符号位置的属性。不是以前的字符属性,而是文档中任何地方的前一个插入符号位置。(看图片。)我希望这不是预期的行为。那么我一定是做错了什么。你知道吗?拜托。这可能意味着在更新输入样式之前调用了你的caretListener。无论如何,我总是对JTextPane的默认样式计算有问题,所以我自己做了。你可以做的是停止转发输入属性,并在选择开始之前使用或字符的属性(即使没有选择也可以使用),或者如果插入符号正好位于新行(\n)之后或文档开头,则使用默认样式