соединение двух JTextAreas в Java (обновление) - PullRequest
2 голосов
/ 13 июля 2011

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

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

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

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

«меньшие текстовые поля»

  1. Привет.

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

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

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

Ответы [ 4 ]

1 голос
/ 13 июля 2011

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

1 голос
/ 13 июля 2011

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

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

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

  • вставка символов
  • удаление символов
  • смена символов

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

1 голос
/ 13 июля 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 &lt I_SubTextField &gt registeredSubTextAreas = new ArrayList &lt I_SubTextField &gt ();

    /**
     * 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, поэтому вы можете зарегистрировать дополнительные SubTextFields в SubTextField.

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

1 голос
/ 13 июля 2011

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

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

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

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

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

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

...