在java中连接两个JTextAreas(更新)

时间:2011-07-12 20:19:28

标签: java swing actionlistener jtextarea

我有一个大型的JTextArea,用户可以在其中输入一堆文本。我的程序允许用户选择一些文本并使用所选文本创建较小的JTextAreas以进行更密切的分析(编辑等)。

用户可以更新更大或更小的JTextAreas,当他们这样做时,我希望另一个更新到这个新文本。

我的问题是获取大型JTextArea中的文本以及较小的文本以相互引用。有这样做的好方法吗?我很难分割大文本区域并同时使用文档监听器。当文本与较小的文本区域重叠时会变得很困难。

离。 “大文字区” 你好。我的名字是Matthieu,我对所有这些文本框感到沮丧:p。

“较小的文字区域”

  1. 您好。

  2. 所有这些文本框:p。

  3. 文本框:p。

  4. 如果我在2中将“文本框”更改为“apple”,则框3和全文应相应更新!

4 个答案:

答案 0 :(得分:1)

这可能不是你想听到的,但这听起来是一个非常糟糕的主意......第一个原因是在代码和设计中管理起来非常复杂。第二个原因是它使用户使用它变得更加复杂......

如果你真的想以这种方式实现它,我会说最好的方法是保留一个正在编辑的片段列表,并在该列表中添加一个包含起始索引,原始文本和哪个正在编辑的文本框。

然后,只要在任何文本框中进行任何更改,运行一个方法对所有文本框进行更改,并使用更新的原始文本和起始索引更新列表中的所有项目。

老实说,我看不到一个简单的方法,你拥有的文本框越多,它的速度就越慢。

在我看来,更好的设计就像JEditorpane,只显示显示静态文本的文本(作为大文本框),单个文本框显示所选文本并允许编辑。这使得编码非常简单,但(可能更重要的是),它使用户界面更简单,更清晰。

如果不确切知道为什么需要这个,我不能确定第二种方式会更好,但我宁愿使用更简单的应用作为用户。

答案 1 :(得分:1)

这可能非常困难,具体取决于您希望最终结果。在我看来,你需要跟踪选择的开始和结束以及每个框。当文本在#2中更改时,您可以替换从#2开始索引开始到结束索引结束的原始长文本。那可能没问题。

我在哪里看到问题就是你在#2中间插入“dumb”之类的东西。你会如何处理#3?你会改变#3的起始索引来补偿,还是会改变#3引用的文本,所以它会说“哑测试b”?

在您对此进行更多编码之前,我认为您应该在逻辑上完成您想要发生的事情,至少:

  • 插入字符
  • 删除字符
  • 更改字符

并且可能会与听众逐个字符地处理它。这一切都取决于你想要的最终结果。

答案 2 :(得分:1)

您需要做的就是为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()

答案 3 :(得分:1)

我会在所有文本区域使用相同的模型(Document)。尝试覆盖JTextArea中使用的View以仅显示所需的片段。 (参见PlainView资源)。