Как использовать Caret, чтобы узнать, в какой строке он находится от JTextPane? (Джава) - PullRequest
2 голосов
/ 01 мая 2010

Проблема: у меня есть CaretListener и DocumentListener, прослушивающие JTextPane.

Мне нужен алгоритм, который может определить, какая строка является кареткой в ​​JTextPane, вот иллюстративный пример:

alt text

Результат: 3-я строка

alt text

Результат: 2-я строка

alt text

Результат:4-я строка

, и если алгоритм может определить, какая строка каретки находится в JTextPane, должно быть довольно легко вставить все, что находится в скобках, как изображение (каретка имеет символ m из metadata):

alt text

-

Вот как я делю весь текст, полученный из JTextPane, на предложения:

String[] lines = textPane.getText().split("\r?\n|\r", -1);

Предложения в textPane отделены \ n.

Проблема в том, , как я могу манипулировать кареткой, чтобы сообщить мне, в какой позиции и в какой строке она находится?Я знаю, что точка каретки говорит, в каком положении она находится, но Я не могу сказать, какая это линия на .Предполагая, что если я знаю, какая строка является кареткой, тогда я могу просто сделать lines[<line number>] и манипулировать строкой оттуда.

Вкратце: как использовать CaretListener и / или DocumentListener длязнаете какая строка каретки в настоящее время находится в , а извлекает строку для дальнейшей манипуляции со строками?Пожалуйста помоги.Спасибо.

Дайте мне знать, если понадобятся дальнейшие разъяснения.Спасибо за ваше время.

Ответы [ 3 ]

9 голосов
/ 01 мая 2010

Вот исходный код, который вы запросили:

static int getLineOfOffset(JTextComponent comp, int offset) throws BadLocationException {
    Document doc = comp.getDocument();
    if (offset < 0) {
        throw new BadLocationException("Can't translate offset to line", -1);
    } else if (offset > doc.getLength()) {
        throw new BadLocationException("Can't translate offset to line", doc.getLength() + 1);
    } else {
        Element map = doc.getDefaultRootElement();
        return map.getElementIndex(offset);
    }
}

static int getLineStartOffset(JTextComponent comp, int line) throws BadLocationException {
    Element map = comp.getDocument().getDefaultRootElement();
    if (line < 0) {
        throw new BadLocationException("Negative line", -1);
    } else if (line >= map.getElementCount()) {
        throw new BadLocationException("No such line", comp.getDocument().getLength() + 1);
    } else {
        Element lineElem = map.getElement(line);
        return lineElem.getStartOffset();
    }
}

...

public void caretUpdate(CaretEvent e) {
    int dot = e.getDot();
    int line = getLineOfOffset(textComponent, dot);
    int positionInLine = dot - getLineStartOffset(textComponent, line);
    ...
}
2 голосов
/ 01 мая 2010

Используйте понятие абзаца в StyledDocument с JTextPane.getStyledDocument.

С позицией курсора вы знаете текущий абзац с помощью StyledDocument.getParagraph (pos). Затем вы перебираете абзацы из StyledDocument.getRootElements и потомков, чтобы найти номер текущего абзаца и номер текущей строки.

Извините за мой английский.

1 голос
/ 01 мая 2010

Вот как я делю весь текст что я извлек из JTextPane на предложения:

Ваше решение не очень эффективно.

Прежде всего, в документе всегда хранится только "\ n", независимо от того, какая ОС используется. Таким образом, вы можете упростить регулярное выражение.

Однако нет необходимости использовать регулярное выражение для разбора всего документа, поскольку вам важна только одна строка в документе. Теперь, когда вы знаете интерфейс Element, вы можете сделать код более эффективным.

а) получить строку, как показано ранее
б) теперь вы можете получить Элемент, представленный этой строкой, от корневого Элемента
c) теперь вы можете использовать начальные / конечные смещения и метод getText (...), чтобы получить только текст для этой конкретной строки.

...