使用DocumentFilter.FilterBypass

我希望在DocumentFilter上有这样的方法

 public void replaceUpdate(int offset, int length, String text) { try { super.replace(byPass, offset, length, text, null); } catch (BadLocationException ex) { //error } } 

目前为了获得FilterBypass的实例(上面的方法中的byPass),我需要从重写的方法insertString获取:

 private FilterBypass byPass; @Override public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet att) throws BadLocationException { byPass = fb; //some stuff here super.insertString(fb, offset, string, att); } 

但这给我带来了一些问题。 任何人都可以提出一些获得FilterBypass的不同方法吗? 我找不到以不同方式获取FilterBypass引用的FilterBypass

如果我要覆盖它的方法应该怎么做?

例如,这是一个带有DocumentFilter的SSCCE,它可以防止用户在文档中键入数字,但允许Swing Timer这样做。

 import java.awt.event.*; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.text.*; public class DocFilterPanel extends JPanel { private JTextArea textArea = new JTextArea(12, 50); private MyDocFilter myDocFilter = new MyDocFilter(); public DocFilterPanel() { ((PlainDocument) textArea.getDocument()).setDocumentFilter(myDocFilter); int vsbPolicy = JScrollPane.VERTICAL_SCROLLBAR_ALWAYS; int hsbPolicy = JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED; add(new JScrollPane(textArea, vsbPolicy , hsbPolicy)); int timerDelay = 1000; new Timer(timerDelay , new ActionListener() { @Override public void actionPerformed(ActionEvent e) { myDocFilter.setFilter(false); textArea.append("12345\n"); myDocFilter.setFilter(true); } }).start(); } private static void createAndShowGui() { DocFilterPanel docFilterPanel = new DocFilterPanel(); JFrame frame = new JFrame("DocFilterTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(docFilterPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } class MyDocFilter extends DocumentFilter { private static final String REMOVE_REGEX = "\\d"; private boolean filter = true; public boolean isFilter() { return filter; } public void setFilter(boolean filter) { this.filter = filter; } @Override public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { if (filter) { text = text.replaceAll(REMOVE_REGEX, ""); } super.insertString(fb, offset, text, attr); } @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if (filter) { text = text.replaceAll(REMOVE_REGEX, ""); } super.replace(fb, offset, length, text, attrs); } } 

我喜欢@hovercraft的解决方案,但它给了我并发问题。 我通过同步文本区域上的filter来解决这个问题。 喜欢这个:

 synchronized (textArea) { myDocFilter.setFilter(false); textArea.append("12345\n"); myDocFilter.setFilter(true); }