当前位置: 代码迷 >> J2SE >> JComboBox Model過濾數據,该如何解决
  详细解决方案

JComboBox Model過濾數據,该如何解决

热度:565   发布时间:2016-04-24 02:06:27.0
JComboBox Model過濾數據
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");    }    }
  相关解决方案