【问题标题】:How to get a DocumentFilter to work with a JComboBox如何让 DocumentFilter 与 JComboBox 一起工作
【发布时间】:2013-03-24 09:52:03
【问题描述】:

我之前用 DocumentListener 尝试过这个,但这也给了我在听到一些东西后编辑 Document 的问题。现在我正在尝试对 DocumentFilter 做同样的事情,它似乎正在工作。

public class InputField extends JComboBox<String>{

//for finding suggestions
private SuggestionFinder _finder;
//the model to use for adding items
private DefaultComboBoxModel<String> _model;

public InputField(SuggestionFinder finder){
    super();
    _model = new DefaultComboBoxModel();
    this.setModel(_model);
    maximumRowCount = 5;
    this.setEditable(true);
    Dimension d = new Dimension(300, 75);
    this.setMinimumSize(d);
    this.setMaximumSize(d);
    _finder = finder;
    Component edComp = editor.getEditorComponent();
    Document document = ((JTextComponent)edComp).getDocument();
    if (document instanceof PlainDocument) {
     ((PlainDocument) document).setDocumentFilter(new DocumentFilter() {
        @Override
        public void insertString(FilterBypass fb, int offset,
              String string, AttributeSet attr) throws BadLocationException {
            System.out.println("1");
            Document d = fb.getDocument();
            giveSuggestions(d.getText(0, d.getLength()));
            super.insertString(fb, offset, string, attr);
        }

        @Override
        public void remove(FilterBypass fb, int offset, int length)
              throws BadLocationException {
            System.out.println("2");
            Document d = fb.getDocument();
            giveSuggestions(d.getText(0, d.getLength()));
            super.remove(fb, offset, length);
        }

        @Override
        public void replace(FilterBypass fb, int offset, int length,
              String text, AttributeSet attrs) throws BadLocationException {
            System.out.println("3");
            Document d = fb.getDocument();
            giveSuggestions(d.getText(0, d.getLength()));
            super.replace(fb, offset, length, text, attrs);
        }
     });
  }
}

private void giveSuggestions(String word){
    System.out.println(word);
    _model.removeAllElements();
    if (word.equals("")){
        this.hidePopup();
    }
    else{
        this.showPopup();
        /*List<String> suggs = _finder.getSuggestions(word);
        for (int i = 1; i <= suggs.size(); i++){
            _model.addElement(suggs.get(i-1));
        }*/
        for (int i = 0; i < 5; i++){
            System.out.println("adding");
            _model.addElement("" + Math.floor(Math.random()*100));
        }
    }
    System.out.println("done");
}

public static void main(String[] args) throws IOException{
    //instantiate a finder, how I do this isn't really relevant to my issue
    InputField field = new InputField(finder);
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(field);
    frame.pack();
    frame.setVisible(true);
}

【问题讨论】:

    标签: java swing jcombobox keylistener documentfilter


    【解决方案1】:

    有些事情告诉我你不想这样做,而是你真的想使用 DocumentFilter。例如:

    import java.io.IOException;
    import javax.swing.*;
    import javax.swing.text.*;
    
    public class DocFilterEg {
       public static void main(String[] args) throws IOException {
          JPanel panel = new JPanel();      
          InputField2 field2 = new InputField2();
    
          panel.add(field2.getCombo());
    
          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.add(panel);
          frame.pack();
          frame.setVisible(true);
       }
    }
    
    class InputField2 {
       String[] foo = {"1", "2", "3"};
       private JComboBox<String> combo = new JComboBox<String>(foo);
    
       public InputField2() {
          combo.setEditable(true);
          Object editorComponent = combo.getEditor().getEditorComponent();
          Document document = ((JTextComponent)editorComponent).getDocument();
    
          if (document instanceof PlainDocument) {
             ((PlainDocument) document).setDocumentFilter(new DocumentFilter() {
                @Override
                public void insertString(FilterBypass fb, int offset,
                      String string, AttributeSet attr) throws BadLocationException {
    
                   Document doc = fb.getDocument();
                   StringBuilder sb = new StringBuilder();
                   sb.append(doc.getText(0, doc.getLength()));
                   System.out.println("Original String: " + sb.toString());
                   sb.insert(offset, string);
                   System.out.println("New String:      " + sb.toString());
    
                   super.insertString(fb, offset, string, attr);
                }
    
                @Override
                public void remove(FilterBypass fb, int offset, int length)
                      throws BadLocationException {
    
                   Document doc = fb.getDocument();
                   StringBuilder sb = new StringBuilder();
                   sb.append(doc.getText(0, doc.getLength()));
                   System.out.println("Original String: " + sb.toString());
                   sb.delete(offset, offset + length);
                   System.out.println("New String:      " + sb.toString());
    
                   super.remove(fb, offset, length);
                }
    
                @Override
                public void replace(FilterBypass fb, int offset, int length,
                      String text, AttributeSet attrs) throws BadLocationException {
    
                   Document doc = fb.getDocument();
                   StringBuilder sb = new StringBuilder();
                   sb.append(doc.getText(0, doc.getLength()));
                   System.out.println("Original String: " + sb.toString());
                   sb.replace(offset, offset + length, text);
                   System.out.println("New String:      " + sb.toString());
    
                   super.replace(fb, offset, length, text, attrs);
                }
             });
          }
       }
    
       public JComponent getCombo() {
          return combo;
       }
    }
    

    编辑,正如我昨天在你之前的帖子中提到的那样。

    【讨论】:

    • 谢谢,我编辑了它,它现在可以正确捕捉按键。然而,正如我在上面编辑我的问题来解释的那样,一旦我输入第二个字母,我就会得到一个奇怪的无限循环。错误消息是说它发生在我说“this.showPopup()”的那一行,你知道为什么会这样吗?
    • 其实我觉得这是别人给我的一些代码中的错误,谢谢你的帮助!如果我有任何后续问题,我会在这里再次回复。
    • 没关系,这绝对是个问题。出于某种原因,输入第一个字母,然后输入下一个字母会导致程序崩溃。注释掉 'this.showPopup()' 行也无济于事。
    猜你喜欢
    • 2023-02-02
    • 2017-06-25
    • 2020-12-13
    • 2012-02-02
    • 2011-02-22
    • 2016-07-22
    • 2011-08-17
    • 2021-12-18
    • 2015-10-21
    相关资源
    最近更新 更多