подключение двух JTextAreas в java (обновление)

У меня есть большая JTextArea, где пользователи могут вводить кучу текста. Моя программа позволяет пользователям выбирать некоторый текст и создавать меньшие JTextAreas с выделенным текстом для более тщательного анализа (редактирования и т. д.).

Пользователи могут обновлять большие или меньшие JTextAreas, и когда они это сделают, я хочу, чтобы другие тоже обновили этот новый текст.

Моя проблема заключается в том, чтобы текст в большой JTextArea и меньшие ссылались друг на друга. Есть ли хороший способ сделать это? Мне трудно разделить большую текстовую область и одновременно использовать прослушиватели документов. Это становится трудным, когда есть наложение текста из меньших текстовых областей.

бывший. "большая текстовая область" Здравствуйте. Меня зовут Матье, и меня бесят все эти текстовые поля :p.

"меньшие текстовые области"

  1. Привет.

  2. все эти текстовые поля: p.

  3. текстовые поля: стр.

если я изменю «текстовые поля» на «яблоко» в 2, то поле 3 и полный текст должны обновиться соответственно!


person matthieu    schedule 12.07.2011    source источник
comment
Мне так любопытно... с какой стати ты хочешь это сделать?   -  person MirroredFate    schedule 13.07.2011
comment
Идея состоит в том, чтобы брать свои заметки в классе, помещать фрагменты на стикеры и размещать их на своей стене. Если вы случайно заметили ошибку в своем посте, вы можете отредактировать его, и ваши заметки также будут в порядке (и наоборот). Это новый проект.   -  person matthieu    schedule 13.07.2011


Ответы (4)


Это, вероятно, не то, что вы хотите услышать, но это звучит как очень плохая идея... Первая причина заключается в том, что это очень сложно управлять в коде и дизайне. Вторая причина заключается в том, что это усложняет использование пользователем...

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

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

Честно говоря, я не вижу простого способа сделать это, и чем больше у вас текстовых полей, тем медленнее он будет работать.

На мой взгляд, гораздо лучшим дизайном было бы что-то вроде JEditorpane, чтобы просто отображать текст (в виде большого текстового поля), показывающий статический текст, с одним текстовым полем, которое отображает выделенный текст и позволяет редактировать. Это делает код довольно тривиальным, но (возможно, даже более важным) делает пользовательский интерфейс намного проще и чище.

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

person Riaan Cornelius    schedule 12.07.2011
comment
Это очень странно, я согласен, но это то, что требуется. Я добавил краткое описание проекта выше. Я изначально собирался сделать то, что вы предложили, но это быстро стало очень грязным! Спасибо за совет и согласен с потенциальной медлительностью! - person matthieu; 13.07.2011

Это может быть очень сложно, в зависимости от того, какой вы хотите получить конечный результат. Мне кажется, что вам нужно отслеживать начало и конец выбора вместе с каждым из полей. Поскольку текст изменен в № 2, вы можете заменить исходный длинный текст, начиная с начального индекса № 2 и заканчивая конечным индексом. Это может быть нормально.

Я вижу проблему, если вы сделаете что-то вроде вставки «немого» в середине № 2. Как бы вы справились с этим в № 3? Сместите ли вы начальный индекс № 3, чтобы компенсировать это, или вы сместите текст, на который ссылается № 3, чтобы он говорил «тупой тест b»?

Прежде чем вы начнете кодировать это больше, я думаю, вы должны логически проработать то, для чего вы хотите, по крайней мере:

  • вставка символов
  • удаление символов
  • смена персонажей

И, вероятно, разбирайтесь со своими слушателями в индивидуальном порядке. Все зависит от того, какой вы хотите получить конечный результат.

person Jim    schedule 12.07.2011

Все, что вам нужно сделать, это создать подкласс JTextArea и использовать интерфейс. Интерфейс можно использовать, чтобы сообщить подтекстовым областям, что основная текстовая область была обновлена.

Вам понадобятся два подкласса. Одна будет основной текстовой областью, другая — вспомогательными панелями. Вложенные панели реализуют интерфейс, чтобы при обновлении родителя они получали данные. Затем они могут обрабатывать его так, как они хотят.

Области подтекста регистрируются вместе с основной текстовой областью.

Вот рабочий пример:

Main.java Запускает демонстрацию



package Text;

import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;


/**
 *
 * @author dvargo
 */
public class Main
{
    public static void main(String [] args)
    {
        //build the main text area
        JFrame mainFrame = new JFrame();
        mainFrame.setSize(700,700);
        mainFrame.setTitle("Main Frame");
        mainFrame.setLayout(new GridLayout());

        //build a sub text area
        JFrame subFrameA = new JFrame();
        subFrameA.setTitle("Sub Frame A");
        subFrameA.setSize(300,300);
        subFrameA.setLayout(new GridLayout());
        subFrameA.setLocation(mainFrame.getX() + mainFrame.getWidth() + 25, mainFrame.getY());

        //build another sub text area
        JFrame subFrameB = new JFrame();
        subFrameB.setTitle("Sub Frame b");
        subFrameB.setSize(300,300);
        subFrameB.setLayout(new GridLayout());
        subFrameB.setLocation(subFrameA.getX() + subFrameA.getWidth() + 50, subFrameA.getY());

        //this is the main text area. Anything typed into here will be sent to the sub text areas
        TextField mainTextField = new TextField("Type here and text will appear in the sub frames!!!");

        //this sub text area will just mirror the main text area
        SubTextField subTextFieldA = new SubTextField();

        //this sub text area will add a "-" to the begining of every line
        SubTextField subTextFieldB = new SubTextField()
        {

            @Override
            public void update(String text, char lastPressedChar)
            {
                super.update("- " + text.replace("\n", "\n- "),lastPressedChar);
            }
        };

        //register the sub text areas with the main text areas
        mainTextField.register(subTextFieldA);
        mainTextField.register(subTextFieldB);

        //add them to their frames
        mainFrame.add(new JScrollPane(mainTextField));
        subFrameA.add(new JScrollPane(subTextFieldA));
        subFrameB.add(new JScrollPane(subTextFieldB));

        //make everything visible
        mainFrame.setVisible(true);
        subFrameA.setVisible(true);
        subFrameB.setVisible(true);

    }
}


I_SubTextField.java Интерфейс для реализации всех областей подтекста


package Text;

/**
 * Interface to implement to be notified when the text has changed
 * @author dvargo
 */
public interface I_SubTextField
{
    public void update(String text, char lastChar);
}


TextField.java Используйте это как основную текстовую область


package Text;

import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextArea;

/**
 * Text area
 * @author dvargo
 */
public class TextField extends JTextArea
{
    //holds all registered sub text areas that are registered for updates
    List < I_SubTextField > registeredSubTextAreas = new ArrayList < I_SubTextField > ();

    /**
     * Default constructor
     */
    public TextField()
    {
        this("");
    }

    /**
     * Constructor
     * @param text Sets this text area to display this text
     */
    public TextField(String text)
    {
        super(text);
        addListener();
    }

    /**
     * Registers a sub text area to get updates when this text area is updated
     * @param subTextArea
     */
    public void register(I_SubTextField subTextArea)
    {
        registeredSubTextAreas.add(subTextArea);
    }

    /**
     * Unregisters a sub text area to stop receiving updates
     * @param subTextField
     */
    public void unRegister(I_SubTextField subTextField)
    {
        registeredSubTextAreas.remove(subTextField);
    }

    /**
     * Notifies all registered classes when the data in the main window has changed
     */
    private void addListener()
    {
        addKeyListener(new java.awt.event.KeyAdapter()
        {
            public void keyReleased(java.awt.event.KeyEvent evt)
            {
                for (I_SubTextField registeredField : registeredSubTextAreas)
                {
                    registeredField.update(TextField.this.getText(), evt.getKeyChar());
                }
            }
        });
    }

}


SubTextField.java Используйте это для всех подтекстовых областей.


package Text;

/**
 * Represents a sub text area. This can be registered with a TextField to be notified
 * when the data has been updated
 * @author dvargo
 */
public class SubTextField extends TextField implements I_SubTextField
{

    /**
     * Default constructor
     */
    public SubTextField()
    {
        super();
    }

    /**
     * Constructor
     * @param text Text to display in the text area
     */
    public SubTextField(String text)
    {
        super(text);
    }

    /**
     * Called when the parent TextField is updated. Handle the text as you want
     * @param text The text for the main parent
     * @param lastPressedChar The last char the user pressed
     */
    public void update(String text, char lastPressedChar)
    {
        setText(text);
    }

}


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

Вы можете настроить их так, чтобы они регистрировались друг у друга и отправляли друг другу необработанный текст. Затем каждый SubTextField может обрабатывать текст так, как он хочет. Все, что вам нужно сделать, это переопределить update()

person user489041    schedule 12.07.2011
comment
Спасибо! Я только что попробовал это, и это будет хорошая стартовая позиция. Мне также необходимо обновить основной фрейм, когда я набираю текст в подфрейме A или B. Кроме того, подфреймы a и b будут фрагментами текста основного фрейма. Например, основной текст напечатайте здесь, и текст появится в подкадрах!!! может быть разделен на Тип здесь и текст в подфрейме А, но появится в для Б. Изменение Типа здесь и текста в подфрейме А на котенок котенок должен изменить текст основного кадра на котенок котенок котенок появится в подкадрах!!! . - person matthieu; 13.07.2011

Я бы использовал одну и ту же модель (Документ) во всех текстовых областях. Попробуйте переопределить представление, используемое в JTextArea, чтобы отображать только нужный фрагмент. (См. исходники PlainView).

person StanislavL    schedule 13.07.2011