java - 为复选框过滤 JTable 的按钮被选中

标签 java swing jtable rowfilter rowsorter

我有一个与这个非常相似的 JTable。

http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#sorting

table

我已经成功地在它上面设置了一个普通的过滤器(一个搜索功能)并且它运行良好。我想要一个按钮,它会立即仅显示选中素食的行。

好的,现在感谢@peeskillet 和@HovercraftFullOfEels 的帮助,这是我的问题的解决方案:

final TableRowSorter<MovieReviewTableModel> rowSorter = new TableRowSorter<MovieReviewTableModel>(tableModel);



// custom RowFilter 
            RowFilter<MovieReviewTableModel, Integer> filter = new RowFilter<MovieReviewTableModel, Integer>()
            {
                // include method returns true to show the row and false to not show it
                @Override
                public boolean include(RowFilter.Entry<? extends MovieReviewTableModel, ? extends Integer> entry)
                {
                    int modelRow = entry.getIdentifier(); //row index
                    boolean checked = ((Boolean)entry.getModel().getValueAt(modelRow, 3)).booleanValue();
                    System.out.println(checked); // to test the values coming through
                    return checked;
                }

            };

            table.setRowSorter(rowSorter);

            JButton onlyFeatured = new JButton("Only show Featured");
            threeButtonPanel.add(onlyFeatured);

            onlyFeatured.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent event)
                {
                    rowSorter.setRowFilter(filter);
                }
            });

有效!非常感谢大家,我欠你们饮料什么的。 :D

最佳答案

让我们重温教程How to Use Tables: Sorting and Filtering .

In addition to reordering the results, a table sorter can also specify which rows will be displayed. This is known as filtering. TableRowSorter implements filtering using javax.swing.RowFilter objects. RowFilter implements several factory methods that create common kinds of filters.

要看的东西:

  • TableRowSorter . - 我们知道我们需要这个。
  • 哦,他们给了我们一个链接 RowFilter文档。让我们在新的浏览器选项卡中打开它。
  • 但首先是最后一行 RowFilter 实现了几个创建常见类型过滤器的工厂方法。”。我们或许应该看看那些“常见种类”是什么。

行过滤器javadoc

  • 静态方法 - andFilter , dateFilter , notFilter , numberFilter , orFilter , regexFilter .好的,我认得 regexFilter从教程。但是那些其他人,仅凭他们的名字,听起来并不太有前途。也许我们应该自己实现。让我们看看 javadoc 的其余部分

javax.swing.RowFilter<M,I>

Type Parameters:
M - the type of the model; for example PersonModel
I - the type of the identifier; when using TableRowSorter this will be Integer

好的,从这里我们知道两件事。当我们创建自定义 RowFilter ,我们应该传递一个 TableModel type 作为第一个参数,输入Integer表示行号。

RowFilter is used to filter out entries from the model so that they are not shown in the view. For example, a RowFilter associated with a JTable might only allow rows that contain a column with a specific string. The meaning of entry depends on the component type. For example, when a filter is associated with a JTable, an entry corresponds to a row; when associated with a JTree, an entry corresponds to a node.

Subclasses must override the include method to indicate whether the entry should be shown in the view. The Entry argument can be used to obtain the values in each of the columns in that entry

基于这两个段落,我们知道 RowFilter用于过滤掉 View 中不需要的行,如果我们创建自己的行,我们将需要覆盖 include返回是否应显示一行的方法。还有 include方法将有一个 Entry参数,在确定哪一行不返回 true 时,我们可以从中获得我们可能感兴趣的细节。这是 javadoc 给我们的基本示例(指南)

RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
    @Override
    public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
        // do your logic here to return true or false.
    }
};

很酷,但这是什么RowFilter.Entry类,它能给我们提供什么有趣的信息?我们来看看the javadoc .

我们可以看到一个有趣的事情是 getModel() 方法。从中我们可以得到我们的表模型。那么让我们完成实现

private static final int CHECKBOX_COLUMN = 4;
...
RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
    @Override
    public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
        int modelRow = entry.getIdentifier();
        Boolean checked = (Boolean)entry.getModel().getValueAt(modelRow, CHECKBOX_COLUMN);
        return checked;
    }
};

不过分了。现在剩下的就是将过滤器设置为排序器,就像您已经从 Oracle 教程中学到的那样,使用正则表达式过滤器。

这是一个填充演示代码。它没有实现 ActionListener按下按钮。我不想为你做一切。您应该有足够的信息自行处理 :-D 快乐学习!

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class TableBooleanFilterDemo {

    public TableBooleanFilterDemo() {
        JTable table = getTable();
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(table.getModel());
        RowFilter filter = getRowFilter();
        rowSorter.setRowFilter(filter);
        table.setRowSorter(rowSorter);

        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private static final int CHECKBOX_COLUMN = 4;

    private RowFilter getRowFilter() {
        RowFilter<TableModel, Integer> filter = new RowFilter<TableModel, Integer>() {
            @Override
            public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
                int modelRow = entry.getIdentifier();
                Boolean checked = (Boolean)entry.getModel().getValueAt(modelRow, CHECKBOX_COLUMN);
                return checked;
            }
        };
        return filter;
    }

    private JTable getTable() {
        Object[][] data = {
            {"Kathy", "Smith",
                "Snowboarding", new Integer(5), new Boolean(false)},
            {"John", "Doe",
                "Rowing", new Integer(3), new Boolean(true)},
            {"Sue", "Black",
                "Knitting", new Integer(2), new Boolean(false)},
            {"Jane", "White",
                "Speed reading", new Integer(20), new Boolean(true)},
            {"Joe", "Brown",
                "Pool", new Integer(10), new Boolean(false)}
        };
        String[] columnNames = {"First Name",
            "Last Name",
            "Sport",
            "# of Years",
            "Vegetarian"};
        return new JTable(new DefaultTableModel(data, columnNames) {
            public Class getColumnClass(int c) {
                return getValueAt(0, c).getClass();
            }
        });
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new TableBooleanFilterDemo();
            }
        });
    }
}

老实说,我从来没有实现过自己的 RowFilter ,但以上是我在尝试学习新事物时几乎要经历的过程。我花了更长的时间来写这个答案,然后才学会如何去做。必须学会阅读文档,而不仅仅是教程。教程是一个很好的起点,但是一旦遇到更复杂的问题,就需要深入挖掘。与您想学习的任何新技术一样。

关于java - 为复选框过滤 JTable 的按钮被选中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25949055/

相关文章:

java - 我如何确保接口(interface)实现扩展特定类?

java - 仅通过引用进行字符串相等性检查

java - java点击按钮时如何触发退格键事件

java - 要使 glassPane 对 JInternalFrame 可见并有效,需要什么样的巫术?

java - JTable setValueAt 不工作

java - 找不到要构建的任何修订。验证此作业的存储库和分支配置。完成 : FAILURE

java - 如何让 DOM 可以读取 xml 文件?

java - 当 Jlabel 添加到 JButton 之前时如何阻止 JButton 改变位置

java - JTable 不改变外观

java jtable 用新值替换旧值