2011-09-16 4 views
1

GUIに2つのJTextAreasがあり、それぞれのJTextAreaにDocumentListenerがあります。たとえば、テキストエリア番号1にabcを入力すると、そのドキュメントテキストが表示されます何らかの方法でそれを修正し、JTextArea 2のドキュメントに出力してください。Java GUIのドキュメントモデル

私のリスナーと一緒に私はソースドキュメントを手に入れることができます。私はテキストを変更できますが、エラーが出る

例外スレッドで "AWT-EventQueueの-0" java.lang.IllegalStateException:通知に

PLEを変異させる試みaseヘルプ。

おかげ

はここにいくつかのコードです:

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 

/** 
* 
* @author Maxi 
*/ 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 

public class Test { 

    static JFrame frame = new JFrame("CaesarEncipherGUI"); 
    static JPanel panel = new JPanel(); 
    static JTextArea area = new JTextArea(5,20); 



    static JTextArea area1 = new JTextArea(5,20); 


    static class MyDocumentListener2 implements DocumentListener { 

    public void insertUpdate(DocumentEvent e) { 
     updateLog(e,""); 
    } 
    public void removeUpdate(DocumentEvent e) { 
     updateLog(e,""); 

    } 


    public void changedUpdate(DocumentEvent e) { 

    }  


public void updateLog(DocumentEvent e, String action){ 


Document doc = (Document)e.getDocument(); 



try{ 


    System.out.println("Action detected "+doc.getProperty("type")); 

String text = doc.getText(0, doc.getLength()); 

doc.insertString(0, "hey", null); //heres the line that throws the error. 



//mutation of text here 

}catch (BadLocationException catchme2){} 



} 
} 

     public static void main(String[] args){ 



      area.getDocument().addDocumentListener(new MyDocumentListener2()); 

     //initialize 
     frame.setResizable(false); 
     frame.setBounds(300, 300, 235, 400); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 



panel.add(area); 
panel.add(area1); 
frame.add(panel); 
frame.setSize(235,400); 
frame.setVisible(true); 


    } 



} 
+0

リスナーがドキュメント1にあり、ドキュメント2のテキストを変更しようとすると、このエラーが発生しますか?または、あなたが聴いている同じ文書のテキストを変更しようとした場合に限ります。私はそれが後者であり、問​​題はDocumentListener API、「注文に関する保証はありません」のセクションに詳しく記述されていると思います。 1つの解決策は、コードをラップしてRunnableのテキストを変更し、SwingUtilities.invokeLater(...)を介してEDTにキューイングすることです。 –

+0

私がオンラインで読んだところでは、ドキュメントリスナー内のドキュメントテキストを変更しないと思われます。私はどこで文書のテキストの変更を実行しますか? – user541597

+0

再度、EDTの変更をキューイングすることでこれを行うことができます。もう1つ、おそらくもっと良い解決策はDocumentFilterを使うことです。 –

答えて

4

あなたはDocumentListenerはそれがを聞いているのと同じドキュメント上のテキストを変更持つようにしようとしている可能性が高いです。

DocumentEvent通知は、JavaBeansイベントモデルに基づいています。DocumentListener APIには許可されていません。リスナーへの納品の順番は保証されておらず、すべてのリスナーは、ドキュメントにさらに突然変異を加える前に通知を受ける必要があります。つまり、DocumentListenerの実装では、イベントのソース(つまり関連するドキュメント)を変更することはできません。

これを回避する方法の1つは、文書のテキストをRunnableに変更し、それをSwingUtilities.invokeLater(...)でEDTにキューイングすることです。

もう1つの解決策は、DocumentFilterを使用することです。 DocumentListenerと

例:

static class MyDocumentListener2 implements DocumentListener { 
     private boolean updating = false; 

     public void insertUpdate(DocumentEvent e) { 
     updateLog(e, ""); 
     } 

     public void removeUpdate(DocumentEvent e) { 
     updateLog(e, ""); 

     } 

     public void changedUpdate(DocumentEvent e) { 

     } 

     public void updateLog(DocumentEvent e, String action) { 
     if (updating) { 
      return; 
     } 
     updating = true; 

     final Document doc = (Document) e.getDocument(); 

     try { 

      System.out.println("Action detected " + doc.getProperty("type")); 

      final String text = doc.getText(0, doc.getLength()); 

      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        try { 
        doc.insertString(0, "hey", null); 
        updating = false; 
        } catch (BadLocationException e) { 
        e.printStackTrace(); 
        } 
       } 
      }); 

     } catch (BadLocationException catchme2) { 
      catchme2.printStackTrace(); 
     } 

     } 
    } 

そして大文字にすべてのテキストをオンDocumentListenerとDocumentFilter例:I場合

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

public class Foo003 { 
    private static final String ENTER = "enter"; 

    public static void main(String[] args) { 
     final JTextArea myArea = new JTextArea(10, 20); 
     final PlainDocument myDocument = (PlainDocument) myArea.getDocument(); 

     DocumentListener myDocumentListener = new DocumentListener() { 
     private boolean changing = false; 

     public void removeUpdate(DocumentEvent e) {} 

     public void changedUpdate(DocumentEvent e) { 
      toUpperCase(myArea, myDocument); 
     } 

     @Override 
     public void insertUpdate(DocumentEvent e) { 
      toUpperCase(myArea, myDocument); 
     } 

     private void toUpperCase(final JTextArea myArea, 
       final PlainDocument myDocument) { 
      if (changing) { 
       return; 
      } 
      try { 
       changing = true; 
       final String text = myDocument 
        .getText(0, myDocument.getLength()).toUpperCase(); 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
        myArea.setText(text); 
        changing = false; 
        } 
       }); 
      } catch (BadLocationException e1) { 
       e1.printStackTrace(); 
      } 
     } 

     }; 

     myDocument.addDocumentListener(myDocumentListener); 

     JOptionPane.showMessageDialog(null, new JScrollPane(myArea), 
      "With DocumentListener", JOptionPane.INFORMATION_MESSAGE); 

     myDocument.removeDocumentListener(myDocumentListener); 

     myArea.setText(""); 

     myDocument.setDocumentFilter(new DocumentFilter() { 
     @Override 
     public void insertString(FilterBypass fb, int offset, String text, 
       AttributeSet attr) throws BadLocationException { 
      text = text.toUpperCase(); 
      super.insertString(fb, offset, text, attr); 
     } 

     @Override 
     public void replace(FilterBypass fb, int offset, int length, 
       String text, AttributeSet attrs) throws BadLocationException { 
      text = text.toUpperCase(); 
      super.replace(fb, offset, length, text, attrs); 
     } 
     }); 
     JOptionPane.showMessageDialog(null, new JScrollPane(myArea), 
      "With DocumentFilter", JOptionPane.INFORMATION_MESSAGE); 
    } 
} 

メソッドでは、DocumentListenerとDocumentFilters(と誰かの主な違いは、私を修正します'm wrong!)は、DocumentListenersが更新される前にDocumentFilterが起動している間に、そのDocumentListenersが更新された後に起動するということです。

+0

これを行うためのコード例をいくつか教えてください。また、私が変更しようとしているドキュメントは別のドキュメントですが、同じエラーが発生します。 – user541597

+0

あなたの問題を示す[sscce](http://sscce.org)を作成した場合、私はそれを修正しようとします。 –

+0

上記のsscceeを追加しました。 – user541597