1

我有一系列沿 jTable 的文本框和组合框。我使用框中的输入来过滤 JPQL 查询的结果,这些结果显示在 jTable 上。现在,这个想法是自动化这个过程,这样每次用户在框中键入一个字符时,应用程序都会自动发送查询并使用过滤结果更新 jTable。我试着这样做:

public class MyKeyListener extends KeyAdapter{
   public void keyPressed(KeyEvent evt){
      setFilters();
      displayResults(); }}

setFilters() 和 displayResults() 分别是设置参数和查询并获取 ResultList 和更新 jTable 的方法。然后我将 keyPressed 添加到所有相关的文本框,以及一些 System.out.println 行以进行调试。发生的事情如下:当我输入第一个字符时,什么也没有发生。如果我输入第二个字符,KeyListener 会起作用并发送查询,但仅使用第二个字符进行过滤,则忽略第一个字符。这是我的第一个怪事。第二个是,看着我的控制台,我意识到每个成功的 Key Listened 都会发送 6 次查询。帮助将不胜感激。再三考虑,我还插入了我的 setFilters() 和 displayResults()。

  private void setFilters() {

    //Auslesen der gesetzten Filter
    String name=jName.getText()+"%";
    String vorname= jVorname.getText()+"%";
    String vvname= jVName.getText()+"%";
    String vvorname=jVVorname.getText()+"%";
    String mname=jMName.getText()+"%";
    String strasse=jAdresse.getText()+"%";
    String plz=jPlz.getText()+"%";
    String ort=jOrt.getText()+"%";
    String gruppe=jGruppe.getText()+"%";
    String geschlecht=(String) jGeschlecht.getSelectedItem()+"%";
    String mvorname=jMVorname.getText()+"%";
    String firma=jFirma.getText()+"%";



    //Die Query
    kinderQuery = java.beans.Beans.isDesignTime() ? null : rcwPUEntityManager.createQuery("SELECT k FROM Kinder k "
            + "INNER JOIN k.vaeter vat "
            + "INNER JOIN k.muetter mut "
            + "INNER JOIN k.gruppen gru "
            + "INNER JOIN k.firmen fir "
            + "WHERE k.kindName LIKE :name "
            + "AND k.kindVorname LIKE :vorname "
            + "AND vat.vaterName LIKE :vname "
            + "AND vat.vaterVorname LIKE :vvorname "
            + "AND mut.mutterName LIKE :mname "
            + "AND mut.mutterVorname LIKE :mvorname "
            + "AND k.kindStrasse LIKE :strasse "
            + "AND k.kindPLZ LIKE :plz "
            + "AND k.kindOrt LIKE :ort "
            + "AND gru.gruppeName LIKE :gruppe "
            + "AND k.kindGeschlecht LIKE :geschlecht "
            + "AND fir.firmaName LIKE :firma ");


           //Einsetzen der ausgelesenen Strings in die JPQL-Query Parameter
    kinderQuery.setParameter("name", name);
    kinderQuery.setParameter("vorname", vorname);
    kinderQuery.setParameter("vname", vvname);
    kinderQuery.setParameter("vvorname", vvorname);
    kinderQuery.setParameter("mname", mname);
    kinderQuery.setParameter("mvorname", mvorname);
    kinderQuery.setParameter("strasse", strasse);
    kinderQuery.setParameter("plz", plz);
    kinderQuery.setParameter("ort", ort);
    kinderQuery.setParameter("gruppe", gruppe);
    kinderQuery.setParameter("geschlecht", geschlecht);
    kinderQuery.setParameter("firma", firma);

}

 private void displayResults(){
    java.util.Collection data = kinderQuery.getResultList();
    System.out.println(data);
    kinderList.clear();
    kinderList.addAll(data);
    jTable1.repaint();
}

提前致谢 !

4

2 回答 2

3

问题是生成 keyPressed 事件时,文本字段使用的 Document 尚未更新。您可以监听 keyTyped 事件,但我不推荐这样做,因为它不是最好的解决方案,而且 Swing 提供了更好的 API 来使用。

更好的方法是使用专门为此目的设计的 DocumentListener。阅读 Swing 教程中有关如何编写文档侦听器的部分以获取示例和说明。

于 2011-03-02T15:40:44.193 回答
0

这几乎是如何做到的。使用这种方法而不是使用这种方法的几个好处keyPressed是,当您将一些文本粘贴到字段中时它也可以工作,并且很容易避免对删除等进行所有过滤。

// in your frame or panel
Document doc = new PlainDocument();
doc.addDocumentListener(new MyDocumentListener());

JTextField textField = new JTextField(15);
textField.setDocument(doc);

add(textField);

private class MyDocumentListener implements DocumentListener
{
    public void insertUpdate(DocumentEvent documentEvent)
    {
        // Do your stuff here
        System.out.println("insert detected!");
    }

    public void removeUpdate(DocumentEvent documentEvent)
    {
        // ignore this
    }

    public void changedUpdate(DocumentEvent documentEvent)
    {
        // ignore this
    }
}

并且为了避免对用户可能输入到文本字段中的每件奇怪的事情进行搜索和过滤往返,您应该考虑自己实现只接受某些字符的 PlainDocument。

private class MyDocument extends PlainDocument
{
    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
    {
        StringBuilder builder = new StringBuilder(getText(0, getLength()));
        builder.insert(offs, str);

        if (builder.toString().matches("[A-Za-z]*"))
        {
            super.insertString(offs, str, a);
        }
    }
}
于 2011-03-02T15:59:57.097 回答