Search code examples
javaattributesselectionjtextpanecaret

Get attributes of selected text in JTextPane


I'm trying to find out how to get the attributes of some selected text in JTextPane. I found that the best solution is to do it with getInputAttributes() and CaretListener, but I have some issues with this implementation.

Here's my solution showing the attributes of the text on the last position of the caret, but not on the actual position of the caret. What am I doing wrong? Please.

enter image description here

Here is my 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)));
    }   
}}

And I have two bonus questions. Is this approach functional for selection or just for the position of caret? And what returns, if there is a selection of text where one part is bold and second part is not?


Solution

  • Actually attributes of selection is complicated question and need your understanding of business requirements.

    Suppose a fragment of text is selected and you need the selection font size. But the fragment has 3 different pieces of text with 3 different sizes.

    Selection start position is placed in the mid of 10pt text, then piece of text with 12pt size and selection ends in the mid of 14pt size fragment.

    What size do you expect? 10, 12, 14 or (multiple)?

    The simplest approach is to use inputAttributes.

    By default the attributes are copied from caret position but of course you can add a caret listener and on each update check and fill the input attributes as you need according to your business logic (processing the multiple text fragments with different attributes).

    UPDATE: Try to wrap the AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes(); in SwingUtilities.invokeLater() call