获取JTextPane中所选文本的属性

时间:2015-03-08 14:00:19

标签: java attributes selection jtextpane caret

我试图找出如何在JTextPane中获取所选文本的属性。 我发现最好的解决方案是使用getInputAttributes()和CaretListener。但是我对这个实现有一些问题。

我的解决方案显示了插入符最后位置的文本属性,但没有显示插入符号的实际位置。我做错了什么?请。

enter image description here

有我的SSCCE:

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 个答案:

答案 0 :(得分:1)

实际上,选择属性是一个复杂的问题,需要您理解业务需求。

假设选择了一段文本,您需要选择字体大小。但 该片段有3个不同的文本,有3种不同的大小。

选择开始位置放在10pt文本的中间位置,然后是12pt大小的文本,并且选择在14pt大小的片段中间结束。

您期望的尺寸是多少? 10,12,14或(多个)?

最简单的方法是使用inputAttributes。

默认情况下,属性从插入符号位置复制,但当然您可以添加插入符侦听器并在每次更新检查时根据您的业务逻辑(处理具有不同属性的多个文本片段)根据需要填充输入属性。

更新: 尝试将AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes();包装在SwingUtilities.invokeLater()调用

答案 1 :(得分:1)

获取选择的属性没有预期的行为,只是因为选择可以包含具有每个不同属性的字符元素。

您必须明白,getInputAttributes返回textPane为下一个输入计算的最佳属性,而getCharacterAttributes返回当前插入符号位置的属性。在选择的情况下,插入符号是您结束选择的位置。如果您从左到右或从右到左选择了文字,则可以是getSelectionStartgetSelectionEnd

无论如何,我的建议是获取JTextPane的StyledDocument,然后遍历从getSelectionStartgetSelectionEnd的字符元素:

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
}

答案 2 :(得分:0)

我使用@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
}

唯一没有更改的实例是文档完全为空时,getInputAttributes应该可以正常工作。