2012-07-27 93 views
4

我已将文档侦听器添加到JTextPane。我想知道添加或删除了哪些文本,以便在输入某些关键字时采取措施。插入部分工作得很好,但我不知道如何检测文本被删除。如何知道已从JTextPane中删除了哪些文本

插入工作,因为文本在那里,我可以选择它,但删除已经删除了文本,所以我有时会得到不好的位置异常。

我想保留不在引号内的保留字,因此我需要知道删除了什么内容,删除即使是一个字符(如引号)也会产生巨大影响。

我的代码如下:

@Override 
public void insertUpdate(DocumentEvent e) 
{ 
    Document doc = e.getDocument(); 
    String i = ""; 

    try 
    { 
     i = doc.getText(e.getOffset(), e.getLength()); 
    } 
    catch(BadLocationException e1) 
    { 
     e1.printStackTrace(); 
    } 

    System.out.println("INSERT:" + e + ":" + i); 
} 

@Override 
public void removeUpdate(DocumentEvent e) 
{ 
    Document doc = e.getDocument(); 
    String i = ""; 

    try 
    { 
     i = doc.getText(e.getOffset(), e.getLength()); 
    } 
    catch(BadLocationException e1) 
    { 
     e1.printStackTrace(); 
    } 

    System.out.println("REMOVE:" + e + ":" + i); 
} 

回答

4

这是奇怪的是,有没有简单的方法来获取这些信息。

我已经看过Swing库的源代码。当然 - DocumentEvent中有这样的信息,其类型为AbstractDocument$DefaultDocumentEvent,其中包含protected Vector<UndoableEdit> edits,其中包含GapContent$RemoveUndo类型的一个元素,其中包含protected String string,仅在此类中使用(没有其他“包”类获取此类),而此RemoveUndo类没有getter这个字段。

即使toString没有表现出来(因为RemoveUndo没有overrided toString法):

[[email protected] hasBeenDone: true alive: true] 

这太奇怪了我,我相信,有一些其他简单的方法来获取删除的字符串而我只是不知道如何完成它。

一两件事你可以做的是最明显的:

final JTextArea textArea = new JTextArea(); 
    textArea.addKeyListener(new KeyAdapter() { 
     @Override 
     public void keyPressed(KeyEvent e) { 
      previousText = textArea.getText(); 
     } 
    }); 

    textArea.getDocument().addDocumentListener(new DocumentListener() { 
     @Override 
     public void removeUpdate(DocumentEvent e) { 
      if(previousText != null) { 
       String removedStr = previousText.substring(e.getOffset(), e.getOffset() + e.getLength()); 
       System.out.println(removedStr); 
      } 
     } 
     @Override 
     public void insertUpdate(DocumentEvent e) { 
     } 
     @Override 
     public void changedUpdate(DocumentEvent e) { 
     } 
    }); 

其中previousText是一个实例变量。

或(有史以来最讨厌):

textArea.getDocument().addDocumentListener(new DocumentListener() { 
     @Override 
     public void removeUpdate(DocumentEvent e) { 
      String removedString = getRemovedString(e); 
      System.out.println(removedString); 
     } 

     @Override 
     public void insertUpdate(DocumentEvent e) { 
     } 

     @Override 
     public void changedUpdate(DocumentEvent e) { 
     } 
    }); 

加上这个方法:

public static String getRemovedString(DocumentEvent e) { 
    try { 
     Field editsField = null; 
     Field[] fields = CompoundEdit.class.getDeclaredFields(); 
     for(Field f : fields) { 
      if(f.getName().equals("edits")) { 
       editsField = f; 
       break; 
      } 
     } 
     editsField.setAccessible(true); 
     List edits = (List) editsField.get(e); 
     if(edits.size() != 1) { 
      return null; 
     } 

     Class<?> removeUndo = null; 
     for(Class<?> c : GapContent.class.getDeclaredClasses()) { 
      if(c.getSimpleName().equals("RemoveUndo")) { 
       removeUndo = c; 
       break; 
      } 
     } 

     Object removeUndoInstance = edits.get(0); 
     fields = removeUndo.getDeclaredFields(); 

     Field stringField = null; 
     for(Field f : fields) { 
      if(f.getName().equals("string")) { 
       stringField = f; 
       break; 
      } 
     } 

     stringField.setAccessible(true); 
     return (String) stringField.get(removeUndoInstance); 
    } 
    catch(SecurityException e1) { 
     e1.printStackTrace(); 
    } 
    catch(IllegalArgumentException e1) { 
     e1.printStackTrace(); 
    } 
    catch(IllegalAccessException e1) { 
     e1.printStackTrace(); 
    } 
    return null; 
} 
+0

这是讨厌的。 :)不知道我最终会做什么,但感谢一堆努力。 – BigMac66 2012-08-07 15:43:38

2

我有同样的问题比你。而至强解释说,我也有很多帮助。但之后,我找到了一个方法来做到这一点。就我而言,我创建了扩展DefaultStyledDocument自定义StyledDocument中的类:

public class CustomStyledDocument extends DefaultStyledDocument 
    { 


     public CustomStyledDocument() { 
      super(); 
    } 

    @Override 
     public void insertString(int offset, String string, AttributeSet as) throws BadLocationException { 
      super.insertString(offset, string, as); 
    } 

    @Override 
     public void remove(int offset, int i1) throws BadLocationException { 
     String previousText = getText(offset, i1); 
     super.remove(offset, i1); 
    } 

} 

所以,如果你的getText方法调用super.remove(...)之前,你会得到以前的文本。

相关问题