2011-07-12 37 views
2

我有一個很大的JTextArea,用戶可以在其中輸入一堆文本。我的程序允許用戶選擇一些文本並使用選定的文本創建更小的JTextAreas以進行更近的分析(編輯等)。在java中連接兩個JTextAreas(更新)

用戶可以更新更大或更小的JTextAreas,當他們這樣做時,我希望另一個更新到這個新文本。

我的問題是越來越大的JTextArea中的文本和較小的引用對方。有沒有這樣做的好方法?我很難分開大文本區域並同時使用文檔監聽器。當文本與較小的文本區域重疊時,變得困難。

ex。 「大號文字區」 大家好。我的名字是Matthieu,我對這些文本框感到沮喪:p。

「小文本區域」

  1. 你好。

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

  3. text boxes:p。

如果我在2中將「文本框」更改爲「apple」,則框3和全文應相應更新!

+0

我很好奇......你爲什麼要這麼做? – MirroredFate

+0

這個想法就像是把你的課堂筆記和片段放到貼子上,然後貼在你的牆上。如果偶然發現郵件上有錯誤,您可以對其進行編輯並讓筆記做好(反之亦然)。這是一個新穎的項目。 – matthieu

回答

1

這可能不是您想要聽到的,但這聽起來像是一個非常糟糕的主意......第一個原因是在代碼和設計中進行管理非常複雜。第二個原因是它使用戶使用起來更加複雜......

如果你真的想這樣實現它,我會說最好的方法是保留正在編輯的代碼片段列表,然後向該列表中添加一個項目,該項目包含起始索引,原始文本以及正在編輯的文本框。

然後,無論何時在任何文本框中進行任何更改,都可以運行方法對所有文本框,並使用更新的原始文本和起始索引更新列表中的所有項目。

我真的不能看到一個簡單的方法來做到這一點,越多的文本框,它會得到越慢。

在我看來,一個更好的設計就像JEditorpane一樣,只顯示顯示靜態文本的文本(作爲大文本框),並帶有顯示所選文本並允許編輯的單個文本框。這使得編碼變得非常微不足道,但是(可能更重要的是),它使用戶界面更簡單和更清晰。

不知道爲什麼你需要這個,我不能確定第二種方式會更好,但我寧願使用更簡單的應用程序作爲用戶。

+0

這很奇怪,我同意,但這是必需的。我添加了上述項目的簡要說明。我原先着手做你的建議,但很快就變得非常混亂!感謝您的建議,我同意潛在的不景氣! – matthieu

1

這可能是非常困難的,取決於你想要什麼樣的最終結果。它看起來像我需要跟蹤每個框與開始和結束的選擇。隨着文本在#2中的更改,您可以替換從#2開始索引處開始到結束索引處的原始長文本。這可能是好的。

我發現問題的地方在於如果你在#2的中間插入「啞」字。你會如何處理#3?你會改變#3的開始索引來補償,還是你會移動#3所引用的文字,以便說「啞測試b」?

之前你的代碼這個多了,我想你應該在邏輯上過要發生什麼工作,在最少:

  • 插入字符
  • 刪除字符
  • 變化特徵

而且可能在你的聽衆的角色基礎上處理它。這一切都取決於你想要的最終結果。

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是一個子類文本字段,所以你可以將附加的SubTextFields註冊到SubTextField。

您可以將它們設置爲相互註冊並將未處理的文本發送給對方。然後,每個SubTextField都可以按照需要的方式處理文本。所有你需要做的是覆蓋更新()

+0

謝謝!我只是試了一下,這將是一個很好的起點。 當我在子框架A或B中鍵入文本時,我還需要更新主框架。還有,子框架a和b將成爲大型機文本的片段。 例如,主文本「類型在這裏和文本將出現在子幀!!!」可能會在子幀A中被分成「鍵入此處和文本」,但「將出現在」B中。將子幀A中的「鍵入此處和文本」更改爲「kitty kitty kitty」應將主框架文本更改爲「kitty kitty kitty會出現在子幀!!!「。 – matthieu

1

我會在所有的文本區域使用相同的模型(文檔)。嘗試覆蓋JTextArea中使用的視圖以僅顯示所需的片段。 (請參閱PlainView來源)。