代码之家  ›  专栏  ›  技术社区  ›  Rated

过滤-如何使JTable显示x字段数量

  •  1
  • Rated  · 技术社区  · 10 年前

    我有一个 JTable 它使用 RowFilter 过滤字段,但我希望这些结果缩小到x数量,例如5

    1 回复  |  直到 10 年前
        1
  •  1
  •   MadProgrammer    10 年前

    这很有趣。

    基本上 RowFilter 要知道 RowSorter 将要检查包含的行,因此不能在 行筛选器 然后开始返回 false 在预定极限之后。这个 行排序器 也不能保证它实际上会以任何顺序或作为一个整体查找包含的行。。。它可以检查随机线,例如。。。

    不过,您可以做的是创建一个 行排序器 并超越它 sort 方法,该方法通常在基础模型以某种方式更改或模型引用本身更改时调用。在这里,您可以告诉 行筛选器 它需要重置它的计数。

    行排序器

    基本上,这是 TableRowSorter 寻找一种特殊类型的 行筛选器 并将其称为 reset 方法时,这意味着将已过滤回的行数重置为 0

    public class MyRowSorter extends TableRowSorter<TableModel> {
    
        public MyRowSorter(TableModel model) {
            super(model);
        }
    
        @Override
        public void sort() {
            RowFilter<? super TableModel, ? super Integer> filter = getRowFilter();
            if (filter instanceof LimitedRowFilter) {
                LimitedRowFilter lrf = (LimitedRowFilter) filter;
                lrf.reset();
            }
            super.sort(); 
        }
    
    }
    

    这个 LimitedRowFilter

    这是一个特殊的, 行筛选器 它提供了 lineCount lineLimit 其可被实现用于检查过滤的线的数量是否超过允许的线的最大数量。

    它还提供 重置 使用的方法 行排序器

    这可以使用一些其他功能,如 includeAndIncrement 可能会返回 true 如果应包含该行或 假的 如果它将超过行计数限制 行计数 自动地

    public abstract class LimitedRowFilter<M, I> extends RowFilter<M, I> {
    
        private int lineLimit;
        private int lineCount;
    
        public void reset() {
            lineCount = 0;
        }
    
        public int getLineCount() {
            return lineCount;
        }
    
        public void incrementLineCount() {
            lineCount++;
        }
    
        public int getLineLimit() {
            return lineLimit;
        }
    
        public void setLineLimit(int lineLimit) {
            this.lineLimit = lineLimit;
        }
    
        public LimitedRowFilter(int lineLimit) {
            this.lineLimit = lineLimit;
        }
    
        public LimitedRowFilter() {
        }
    
    }
    

    一个 受限行筛选器

    这是 受限行筛选器 实际上,它基本上会回归 真的 对于每一行,达到允许的最大限制。。。

    public class MyRowFilter extends LimitedRowFilter<TableModel, Integer> {
    
        public MyRowFilter() {
            super();
        }
    
        public MyRowFilter(int limit) {
            super(limit);
        }
    
        @Override
        public boolean include(Entry<? extends TableModel, ? extends Integer> entry) {
    
            boolean included = true;
            // Do you own checking here to determine if the row should be included or
            // not
            if (included) {
                if (getLineCount() < getLineLimit()) {
                    incrementLineCount();
                } else {
                    included = false;
                }
            }
    
            return included;
    
        }
    
    }
    

    一个可运行的示例

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.text.Collator;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    import javax.swing.DefaultRowSorter;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.RowFilter;
    import javax.swing.RowSorter;
    import javax.swing.SortOrder;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    import javax.swing.table.TableRowSorter;
    
    public class LimitedTableRowFilter {
    
        public static void main(String[] args) {
            new LimitedTableRowFilter();
        }
    
        public LimitedTableRowFilter() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
                    DefaultTableModel model = new DefaultTableModel(new Object[]{"A"}, 0);
                    for (int index = 0; index < 100; index++) {
                        model.addRow(new Object[]{index});
                    }
                    JTable table = new JTable(model);
                    MyRowSorter sorter = new MyRowSorter(model);
                    MyRowFilter filter = new MyRowFilter(10);
    
                    sorter.setRowFilter(filter);
                    table.setRowSorter(sorter);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new JScrollPane(table));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    免责声明

    我将第一个承认这是一个不太完美的解决方案,但这比必须复制整个源代码 DefaultRowSorter 表行排序器 这样我们就可以访问 private 我们需要使用的方法来直接在分类器本身内实现功能。

    我只做了有限的测试,所以你可能需要自己做一些调整。。。