2015-03-08 2 views
0

Я пытаюсь выяснить, как получить атрибуты выбранного текста в JTextPane. Я нашел, что лучшее решение - это делать с getInputAttributes() и CaretListener. Но у меня есть некоторые проблемы с этой реализацией.Получить атрибуты выделенного текста в JTextPane

Мое решение, показывающее атрибуты текста в последнем положении каретки, но не на фактическом положении каретки. Что я делаю неправильно? Пожалуйста.

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))); 
    } 
}} 

И у меня есть два бонус вопрос. Является ли этот подход функциональным для выбора или просто для позиции каретки? И что возвращается, если есть выбор текста, одна часть которого выделена жирным шрифтом, а вторая - нет?

ответ

1

На самом деле атрибуты выбора - это сложный вопрос и нуждаются в вашем понимании требований бизнеса.

Предположим, что фрагмент текста выбран, и вам нужен размер шрифта выбора. Но фрагмент имеет 3 разных фрагмента текста с 3 различными размерами.

Начальное положение выбора размещено в середине текста 10pt, затем фрагмент текста с размером и размером 12pt заканчивается в середине фрагмента размера 14pt.

Какой размер вы ожидаете? 10, 12, 14 или (несколько)?

Самый простой способ - использовать inputAttributes.

По умолчанию атрибуты скопированы из позиции курсора, но, конечно, вы можете добавить слушателя каттера и каждую проверку обновлений и заполнить входные атрибуты по мере необходимости в соответствии с вашей бизнес-логикой (обработка фрагментов текста с различными атрибутами) ,

UPDATE: Попробуйте обернуть AttributeSet attrs =((StyledEditorKit)pane.getEditorKit()).getInputAttributes(); в SwingUtilities.invokeLater() вызов

+0

Определенно полезный ответ, я буду использовать его позже. Но сначала мне нужно знать, почему метод getInputAttributes() в моем CaretListener возвращает атрибуты предыдущей позиции каретки. –

+0

Это потому, что обычно это ожидаемое поведение: если вы разместите свой текст после жирного текста, вы, как правило, ожидаете, что ваш ввод будет полужирным, а также – Sharcoux

+0

Ответ был обновлен – StanislavL

1

Там не ожидаемое поведение для получения атрибутов выбора, просто потому, что выбор может иметь элементы символов друг с различными атрибутами.

Вы должны понимать, что существует разница между getInputAttributes, которая возвращает атрибуты, которые textPane рассчитывает наилучшим образом для следующего ввода, и getCharacterAttributes, который возвращает атрибуты текущей позиции каретки. В случае выбора кареткой является позиция, в которой вы закончили выбор. Это может быть getSelectionStart или getSelectionEnd, если вы выбрали текст слева направо или справа налево.

Во всяком случае, я советую вам, чтобы получить StyledDocument вашего JTextPane, а затем перебирать элементы символов из 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 
} 
+0

Спасибо, я уже использую это для выбранного текста. Но если нет выбора, он не работает должным образом в некоторых особых случаях. Если нет выбора, я хочу атрибуты, которые будут использоваться для текста, что будет писать. Я ожидал, что это возврат метода getInputAttributes(), и это похоже. Но это дает мне атрибуты последней позиции каретки. Не предыдущие атрибуты символов, а предыдущая позиция каретки в любом месте документа. (Посмотрите на картинку.) Надеюсь, этого не ожидается. Тогда я должен сделать что-то не так. Знаешь что? Пожалуйста. –

+0

Это, вероятно, означает, что ваш оператор curtListener вызывается до обновления стиля ввода. Во всяком случае, у меня всегда были проблемы с вычислением стиля по умолчанию для JTextPane, поэтому я закончил свою работу. То, что вы можете сделать, это остановить ретрансляцию на inputAttributes и использовать или атрибуты символа перед selectStart (он работает даже без выбора) или стиль по умолчанию, если каретка находится сразу после новой строки (\ n) или на начало документа – Sharcoux

0

Я использовал решение @Sharcoux «с с одним изменением: I убедитесь, что там всегда есть по крайней мере один символ для перебора. Когда нет выбора, 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 должно работать нормально.

Смежные вопросы