- Java code
import javax.swing.ComboBoxModel;import javax.swing.DefaultComboBoxModel;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JTextField;import javax.swing.event.DocumentEvent;import javax.swing.event.DocumentListener;import javax.swing.text.PlainDocument;public class FilterJComboBox extends JComboBox{ private FilterJComboBox self;// private UpperCaseDocument upperCaseDocument; private MyDocumentListener documentListener; private JTextField jtf; private String[] listItems ; public static void main(String...args){ JFrame frame = new JFrame("FilterJComboBoxTest"); FilterJComboBox filterComboBox = new FilterJComboBox(); frame.getContentPane().add(filterComboBox); frame.setVisible(true); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // BasicComboBoxEditor b; } public FilterJComboBox(){ super(); self = this; this.setEditable(true); this.setModel(new FilterModel()); jtf = (JTextField)this.getEditor().getEditorComponent();// upperCaseDocument = new UpperCaseDocument(jtf);// upperCaseDocument.SetOnlyFirstLetterCapitalize(true); documentListener = new MyDocumentListener(); io
在調用refilter的時候會報錯,Attempt to mutate in notification。請問怎麼解決?
我想實現的功能就是:當用戶鍵入首字母時,從model中過濾出符合條件的數據。
不要用KeyListener,那樣效率太低了
------解决方案--------------------
出错的位置在AbsractDocument,也就是所有document的基类中,一个writeLock方法。读一下注释和代码:
原因在于在处理修改的事件中,你又要再次修改,从而导致再次触发修改。无论直接还是间接,这都是不允许的,一次也不允许。
至于你的想法,你得说的详细点。我敲键盘,打了一个a,这个时候你的编辑区域,是出现什么?选中的那个吗?如果是选中的,那么必须修改编辑区域,这就导致再次修改。即使你调用的是jcombobox的方法,但只要选中项改变(你的remove。insert操作都会触发这个操作),就会使得编辑区域的值再次改变。
尽管也许你经过有限的步数之后会终止,不会无限的循环操作下去,但是,如之前所言。不允许。
所以,请调整你的思路,明白事件的限制,明白那些可做,那些不行,再进行设计,不然,一些东西,很可能无法实现,即使,勉强实现了,也有许多的漏洞。倒不如,从一开始就寻求一种可以接受的替代方法。
一家之言,仅供参考交流。
- Java code
protected synchronized final void writeLock() { try { while ((numReaders > 0) || (currWriter != null)) { if (Thread.currentThread() == currWriter) { if (notifyingListeners) { // Assuming one doesn't do something wrong in a // subclass this should only happen if a // DocumentListener tries to mutate the document. throw new IllegalStateException( "Attempt to mutate in notification"); } numWriters++; return; } wait(); } currWriter = Thread.currentThread(); numWriters = 1; } catch (InterruptedException e) { throw new Error("Interrupted attempt to aquire write lock"); } }