【问题标题】:JTable filter on DocumentListener not workingDocumentListener 上的 JTable 过滤器不起作用
【发布时间】:2014-03-10 02:16:33
【问题描述】:
  //Registration filter
    final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(databaseModel);
    DocumentListener idListener = new DocumentListener() {

        public void changedUpdate(DocumentEvent documentEvent) {

        }
        public void insertUpdate(DocumentEvent documentEvent) {
            String searchText = txtReg.getText();
            if (searchText.length() == 0) {
              sorter.setRowFilter(null);
            } else {
              sorter.setRowFilter(RowFilter.regexFilter(searchText));
            }
            numberOfRecords.setText(searchTable.getRowCount() + " records");
        }
        public void removeUpdate(DocumentEvent documentEvent) {

            }


    };
   txtReg.getDocument().addDocumentListener(idListener);

我又来了,可能是一些愚蠢的问题... :( 我有一个 JTable,我希望在我在文本字段上键入时过滤掉。经过一番研究后,我想出了这个,但它不起作用!如果我将过滤器放在侦听器之外,并使用任意字符串作为搜索词,它就可以完美运行。我错过了什么?谢谢!

public class GUI extends JFrame {
private static final long serialVersionUID = -7968397937566078184L;
private static final JLabel numberOfRecords = new JLabel();
private static int numberOfRows;
private static DefaultTableModel databaseModel;



public GUI(DefaultTableModel database){
    setDefaultLookAndFeelDecorated(true);
    setLayout(new MigLayout());
    databaseModel = database;
    //Menus
    JMenuBar menubar = new JMenuBar();
    JMenu file = new JMenu("File");
    JMenuItem update = new JMenuItem("Look for database updates");
    JMenuItem settings = new JMenuItem("Settings");
    JMenuItem exit = new JMenuItem("Exit");
    menubar.add(file);
    file.add(update);
    file.add(settings);
    file.add(exit);
    setJMenuBar(menubar);
     //Top section
    JPanel searchSection = new JPanel();
    searchSection.setLayout(new MigLayout("w 50mm!"));
    final JTextField txtReg = new JTextField(10);
    JLabel searchID = new JLabel("Current registration:");
    JLabel lblManufacturer = new JLabel("Manufacturer");
    JComboBox cmbManufacturer = new JComboBox();
    JLabel lblType = new JLabel("Type");
    JComboBox cmbType = new JComboBox();
    //Build main window
    searchSection.add(searchID);
    searchSection.add(txtReg, "span 2");
    searchSection.add(lblManufacturer);
    searchSection.add(cmbManufacturer, "growx, span 2");
    searchSection.add(lblType);
    searchSection.add(cmbType,"growx, span 2");
    //Table
    final JTable searchTable = new JTable(databaseModel);
    //Pack table, still have to figure this one out
    int width = 0;
     for (int row = 0; row < searchTable.getRowCount(); row++) {
         TableCellRenderer renderer = searchTable.getCellRenderer(row, 2);
         Component comp = searchTable.prepareRenderer(renderer, row, 2);
         width = Math.max (comp.getPreferredSize().width, width);
     }

    searchTable.getColumn("Key").setMaxWidth(0);
    searchTable.getColumn("Key").setMinWidth(0);
    searchTable.setRowSelectionAllowed(true);
    searchTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    searchTable.setAutoCreateRowSorter(true);
    searchTable.getRowSorter().toggleSortOrder(1);
    searchTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    numberOfRows=searchTable.getRowCount();
    JScrollPane browserSP = new JScrollPane(searchTable);
    browserSP.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
    setTitle("AirBase");
    setSize(1300,700);
    setMinimumSize(new Dimension(1250,650));
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    //TODO Fill manufacturer box

    //Registration filter
    //TODO Fix this!
    final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(databaseModel);
    DocumentListener idListener = new DocumentListener() {

        public void changedUpdate(DocumentEvent documentEvent) {

        }
        public void insertUpdate(DocumentEvent documentEvent) {
            String searchText = txtReg.getText();
            if (searchText.length() == 0) {
              sorter.setRowFilter(null);
            } else {
              sorter.setRowFilter(RowFilter.regexFilter(searchText));
            }
            numberOfRecords.setText(searchTable.getRowCount() + " records");
        }
        public void removeUpdate(DocumentEvent documentEvent) {

            }


    };
   txtReg.getDocument().addDocumentListener(idListener);
    add(searchSection, "w 100%, h 5%, wrap");
    add(browserSP,"w 100%, h 95%, wrap");
    numberOfRecords.setFont(numberOfRecords.getFont().deriveFont(9.0f));
    numberOfRecords.setText(numberOfRows + " RECORDS");
    add(numberOfRecords, "alignx center");
}



}

【问题讨论】:

  • 乍一看,您所拥有的一切都很好。您能否提供一个完整的可运行示例,其中包含表的硬编码值,以便我们对其进行测试。
  • @peeskillet 对问题进行了编辑,这就是您所追求的吗? :( 我应该为我的代码感到羞耻吗?哈哈
  • 有点,但您缺少表模型的数据。实际上,您缺少传递给框架的整个表格模型
  • 我应该提到,表模型是在启动时从不应修改的数据库生成的。该表加载得很好,大约有 30k 个条目:)
  • 这不是我所说的硬编码值。由于我们无法测试您的数据库代码,请为您的表模型创建一个完整的可运行/可编译示例,并使用一个main 方法,然后您就可以开始了。除此之外,我创建了一个虚拟 TableModel 并尝试运行您的程序并在启动时遇到一些异常。这就是为什么为我们创建一个可运行的示例很重要。

标签: java swing jtable jtextfield rowfilter


【解决方案1】:

所以我最终开始了它。看起来像一个简单的错误。您忘记了桌子的setRowSorter

searchTable.setRowSorter(sorter);

添加了该代码,它对我有用。应该为你们两个工作,给你一个有效的TableModel 传递给GUI。我只是编了一个假的。

注意事项:

  • 您可能还想将过滤器代码添加到removeUpdate,在DocumentListener 中,这样当文本被退格'd 时,它仍然会过滤。

  • searchTable.getColumn("Key").setMaxWidth(0); 使行数据不可见。这真的是你想要的吗?

  • 如果你想让过滤器不区分大小写过滤,你可以使用这个

    sorter.setRowFilter(RowFilter.regexFilter("(?i)" + searchText));
    

    "(?i)" 是不区分大小写的正则表达式 "flag"

【讨论】:

  • 有效!这么简单的答案!非常感谢,很高兴看到我遇到麻烦时似乎距离解决方案并没有太远。
猜你喜欢
  • 2011-10-27
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多