Java 用于筛选/搜索的Swing JTable定制

Java 用于筛选/搜索的Swing JTable定制,java,swing,filter,jtable,renderer,Java,Swing,Filter,Jtable,Renderer,我想为所有列添加过滤/搜索功能(因此它是通用的)。逻辑没有问题。然而,我认为,就可视化而言,最好的方法是在每个列标题(或列标题的一部分)上方有一个文本字段 我在尝试实现这一目标时遇到了几个问题: 在列标题中嵌入需要实现一个新的渲染器+有一个问题,我需要捕获事件,因为单元格已绘制且不响应事件。在我看来,这是一种过度的杀伤力 在每一列上方有一行(面板)单独的文本字段组件乍看起来容易得多,但是,将文本字段与列对齐是有问题的,因为我在JTable或TableColumn中没有找到返回列坐标的API。此外

我想为所有列添加过滤/搜索功能(因此它是通用的)。逻辑没有问题。然而,我认为,就可视化而言,最好的方法是在每个列标题(或列标题的一部分)上方有一个文本字段

我在尝试实现这一目标时遇到了几个问题:

  • 在列标题中嵌入需要实现一个新的渲染器+有一个问题,我需要捕获事件,因为单元格已绘制且不响应事件。在我看来,这是一种过度的杀伤力
  • 在每一列上方有一行(面板)单独的文本字段组件乍看起来容易得多,但是,将文本字段与列对齐是有问题的,因为我在
    JTable
    TableColumn
    中没有找到返回列坐标的API。此外,移动列也意味着调整文本字段(这是可能的,但另一个开销)
  • 我是错过了什么,还是真的很难做到这么简单的事情?还有其他建议吗

    of visualization is having a textfield above each column header 
    (or part of the column header)... 
    
    • 你看,很简单

    • 用于搜索


      • 有一个库可供您的第一种方法使用。它可以很容易地集成起来,而且效果非常好:

        请参阅下面的一个示例,该示例使用文本字段条目过滤Jtable数据 依赖文本框输入:

        import java.awt.BorderLayout;
        import javax.swing.JApplet;
        import javax.swing.JButton;
        import javax.swing.JLabel;
        import javax.swing.JPanel;
        import javax.swing.JScrollPane;
        import javax.swing.JTable;
        import javax.swing.JTextField;
        import javax.swing.RowFilter;
        import javax.swing.event.DocumentEvent;
        import javax.swing.event.DocumentListener;
        import javax.swing.table.TableModel;
        import javax.swing.table.TableRowSorter;
        
        公共类TestTableSortFilter扩展了JApplet{

        private String[] columnNames
                = {"Country", "Capital", "Population in Millions", "Democracy"};
        
        private Object[][] data = {
            {"USA", "Washington DC", 280, true},
            {"Canada", "Ottawa", 32, true},
            {"United Kingdom", "London", 60, true},
            {"Germany", "Berlin", 83, true},
            {"France", "Paris", 60, true},
            {"Norway", "Oslo", 4.5, true},
            {"India", "New Delhi", 1046, true}
        };
        
        private JTable jTable = new JTable(data, columnNames);
        
        private TableRowSorter<TableModel> rowSorter
                = new TableRowSorter<>(jTable.getModel());
        
        private JTextField jtfFilter = new JTextField();
        private JButton jbtFilter = new JButton("Filter");
        
        public TestTableSorterFilter() {
            jTable.setRowSorter(rowSorter);
        
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(new JLabel("Specify a word to match:"),
                    BorderLayout.WEST);
            panel.add(jtfFilter, BorderLayout.CENTER);
        
            add(panel, BorderLayout.SOUTH);
            add(new JScrollPane(jTable), BorderLayout.CENTER);
        
            jtfFilter.getDocument().addDocumentListener(new DocumentListener(){
        
                @Override
                public void changedUpdate(DocumentEvent arg0) {}
        
                @Override
                public void insertUpdate(DocumentEvent arg0) {
                    String text = jtfFilter.getText();
        
                    if (text.trim().length() == 0) {
                        rowSorter.setRowFilter(null);
                    } else {
                        rowSorter.setRowFilter(RowFilter.regexFilter(text));
                    }   
                }
        
                @Override
                public void removeUpdate(DocumentEvent arg0) {
                    String text = jtfFilter.getText();
                    if (text.trim().length() == 0) {
                        rowSorter.setRowFilter(null);
                    } else {
                        rowSorter.setRowFilter(RowFilter.regexFilter(text));
                    }   
                }
            });
        }
        }
        
        私有字符串[]列名称
        ={“国家”、“首都”、“百万人口”、“民主”};
        私有对象[][]数据={
        {“美国”,“华盛顿特区”,280,真的},
        {“加拿大”、“渥太华”,32,真的},
        {“联合王国”、“伦敦”,60,真的},
        {“德国”,“柏林”,83,真的},
        {“法国”,“巴黎”,60,真的},
        {“挪威”,“奥斯陆”,4.5,真的},
        {“印度”,“新德里”,1046年,真的}
        };
        私有JTable JTable=新的JTable(数据、列名);
        专用表行分拣机行分拣机
        =新的TableRowSorter(jTable.getModel());
        私有JTextField jtfilter=新JTextField();
        私有JButton jbtFilter=新JButton(“过滤器”);
        公共TestTableSorterFilter(){
        jTable.setRowSorter(rowSorter);
        JPanel panel=newjpanel(newborderlayout());
        panel.add(新JLabel(“指定要匹配的单词:”),
        边界布局(西);
        panel.add(jtfilter,BorderLayout.CENTER);
        添加(面板,边界布局。南部);
        添加(新的JScrollPane(jTable),BorderLayout.CENTER);
        jtfilter.getDocument().addDocumentListener(新的DocumentListener()){
        @凌驾
        public void changedUpdate(DocumentEvent arg0){}
        @凌驾
        公共作废插入更新(DocumentEvent arg0){
        String text=jtfilter.getText();
        如果(text.trim().length()==0){
        rowSorter.setRowFilter(空);
        }否则{
        rowSorter.setRowFilter(RowFilter.regexFilter(text));
        }   
        }
        @凌驾
        public void removeUpdate(DocumentEvent arg0){
        String text=jtfilter.getText();
        如果(text.trim().length()==0){
        rowSorter.setRowFilter(空);
        }否则{
        rowSorter.setRowFilter(RowFilter.regexFilter(text));
        }   
        }
        });
        }
        }