Неправильная позиция каретки в JTextPane ?! Ошибка или ожидаемое поведение? - PullRequest
3 голосов
/ 16 января 2012

я наткнулся на следующую проблему:

Я хочу прочитать символ в документе JTextComponent в расположении каретки компонента. Когда я использую JTextPane, символ, возвращенный в позиции каретки, не является правильным. Более подробно, возвращаемым символом является символ - позиция каретки минус номер строки !!! (Позиция каретки - номер текущей строки). С другой стороны, когда я использую JTextArea, результат верный ... Чтобы продемонстрировать это, я реализовал пример программы, с которой можно играть.

Так что большой вопрос, как я могу получить характер позиции каретки в случае JTextPane?

Почему JTextPane не возвращает ту же позицию каретки, что и JTextArea, и более того, почему символ, возвращаемый JTextPane, не тот, который мы можем видеть на экране? Является ли описанное поведение ошибкой?

Ниже вы можете найти код примера программы, а также скриншоты очень интересных и неожиданных результатов

Использование JTextPane. Буква в позиции 17 CARET - это e. Нету ...

альтернативный текст http://img405.imageshack.us/img405/2746/jtextpane.jpg

Использование JTextArea . Здесь у меня есть каретка в той же позиции, что и раньше, но теперь я получаю позицию каретки 20, и буква возврата - \ r \ n (с - ожидаемая).

альтернативный текст http://img809.imageshack.us/img809/5323/jtextarea.jpg

Вот код, с которым вы можете поиграть, чтобы увидеть это странное поведение:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.*;

public class Example extends JFrame {
//  use this instead of JTextPane to see the difference

//  JTextComponent testingArea = new JTextArea(5,10);  
    JTextComponent testingArea = new JTextPane();
JButton button = new JButton("test");
JTextComponent resultArea = new JTextField(20);


public Example() {
    initialise();
    testingArea.setText("line1\r\nline2\r\nline3\r\nline4");
}


private void initialise() {
    testingArea.setPreferredSize(new Dimension(100,100));
    setLayout(new FlowLayout());
    getContentPane().add(testingArea);
    getContentPane().add(new JLabel("answer"));
    getContentPane().add(resultArea);
    getContentPane().add(button);
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            try { 
                int caretPosition = testingArea.getCaretPosition();
                char result = testingArea.getText().charAt(caretPosition);
                resultArea.setText("Char at caretPosition " + caretPosition + " is " + result);
            }catch (Exception e2) {
                e2.printStackTrace();
                resultArea.setText("ERROR");
            }

        }
    });
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    final Example ex = new Example();
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            ex.pack();
            ex.setVisible(true);

        }
    });
}
}

Спасибо за помощь!

PS Я использую Java 6.

Ответы [ 2 ]

5 голосов
/ 16 января 2012

Я думаю, что в JTextPane EOL считается как один символ (\ n, я полагаю), тогда как в JTextArea он считается как два (\ r \ n).

Документация Oracle гласит:

Класс JEditorPane является основой для стилевых текстовых компонентов Swing и предоставляет механизм, с помощью которого вы можете добавить поддержку пользовательских текстовых форматов. Если вы хотите текст без стиля, используйте вместо этого текстовую область.

Таким образом, текстовая область основана только на заданном тексте, поэтому все входные символы считаются. JEditorPane использовал StyledDocument, поэтому EOL может быть интерпретирован.

5 голосов
/ 16 января 2012

Используйте

char result = testingArea.getDocument().getText(caretPosition,1).charAt(0);

вместо

char result = testingArea.getText().charAt(caretPosition);
...