选中了用于过滤JTable的按钮 [英] button to filter JTable for checkbox is selected

查看:98
本文介绍了选中了用于过滤JTable的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与此相似的JTable。




除了重新排序结果外,表格分类器还可以指定要显示的行。这称为过滤。 TableRowSorter 使用 javax.swing.RowFilter 对象。 RowFilter 实现了几种创建常见过滤器的工厂方法。


看看:




  • TableRowSorter 。 - 我们知道我们需要这个。

  • 哦,他们给了我们一个指向 RowFilter docs的链接。让我们在新的浏览器选项卡中打开它。

  • 但是,最后一行 RowFilter 实现了几个创建的工厂方法常见的过滤器。。我们应该看看那些常见种类是什么。



RowFilter javadoc




  • 静态方法 - andFilter dateFilter notFilter numberFilter orFilter regexFilter 。好的,我从教程中认识到 regexFilter 。但其他人,仅凭他们的名字,听起来并不太有希望。也许我们应该实施自己的。让我们看一下javadoc的其余部分




javax.swing.RowFilter< M,I>



类型参数:

M - 模型的类型;例如 PersonModel

I - 标识符的类型;当使用 TableRowSorter 时,这将是整数


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


RowFilter 用于过滤掉模型中的条目,以便它们不会显示在视图中。例如,与 JTable 关联的 RowFilter 可能只允许包含具有特定字符串的列的行。条目的含义取决于组件类型。例如,当过滤器与 JTable 相关联时,条目对应于一行;当与 JTree 相关联时,一个条目对应一个节点。



子类必须覆盖 include 方法,指示是否应在视图中显示该条目。 Entry 参数可用于获取该条目中每个列中的值


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

  RowFilter< TableModel,Integer> filter = new RowFilter< TableModel,Integer>(){
@Override
public boolean include(RowFilter.Entry<?extends TableModel,?extends Integer> entry){
//做你的逻辑这里返回真或假。
}
};

很酷,但这是什么 RowFilter.Entry 课程,它可以为我们提供哪些有趣的信息?我们来看看 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);
返回已检查;
}
};

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



这是一个填充演示代码。按下按钮时,它没有实现 ActionListener 。我不想为你做所有。您应该有足够的信息来自行处理:-D Happy Learning!

  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);
返回已检查;
}
};
返回过滤器;
}

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,
速读,新整数(20),新布尔(真)},
{乔,布朗,
池,新整数(10),新布尔值(假) }
};
String [] columnNames = {名字,
姓氏,
体育,
年数,
素食} ;
返回新的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 ,但上面是我在尝试学习新东西时经历的过程。花了我更长的时间来写这个答案,然后学习如何去做。要学会阅读文档,而不仅仅是教程。教程是一个很好的起点,但是一旦你遇到更复杂的问题,你需要深入挖掘。与您想要学习的任何新技术相同。


I have a JTable fairly similar to this one.

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

I have managed to set a normal filter on it (a search function) and it works well. I want to have a button that will immediately show only the rows where Vegetarian is checked.

Ok so now thanks to the help given by @peeskillet and @HovercraftFullOfEels, this is the solution to my problem:

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);
                }
            });

It works! Thanks so much guys, I owe you drinks or something. :D

解决方案

Let's revisit the tutorial 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.

Things to look at:

  • TableRowSorter. - We know we're going to need this.
  • Oh, they gave us a link to RowFilter docs. Let's open that up in a new browser tab.
  • But first the last line "RowFilter implements several factory methods that create common kinds of filters.". We should probably look to see what those "common kinds" are.

RowFilter javadoc

  • Static methods - andFilter, dateFilter, notFilter, numberFilter, orFilter, regexFilter. Ok, I recognize the regexFilter from the tutorial. But those others, just by their names alone, don't sound too promising. Maybe we should implement our own. Let's look at the rest of the 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

Ok so from this we know two thing. When we create our custom RowFilter, we should pass a TableModel type as the first parameter, and type Integer to represent the row number.

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

So based on those two paragraghs, we know the RowFilter is used to filter out rows we don't want in the view, and that if we create our own, we will need to override the include method to return whether a row should be shown or not. And also the include method will have an Entry argument, from which we can obtain details that may be o interest to us, when determining which row to not return true on. Here's the basic example (guideline) the javadoc gives us

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.
    }
};

Cool, but what is this RowFilter.Entry class, and what interesting information can it provide to us? Let's look at the javadoc.

One interesting thing we can see is the getModel() method. From that we can get our table model. So let's finish the implementation

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;
    }
};

Not much too it. Now all that's left is setting the filter to the sorter, as you learned from the Oracle tutorial already, using the regex filter.

Here's a fill demo code. It doesn't implement the ActionListener for the button press. I didn't want to do everything for you. You should have enough information to handle that on your own :-D Happy Learning!

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();
            }
        });
    }
}

To be honest, I've never had to implement my own RowFilter, but the above is the process I pretty much go through when trying to learn something new. Took me longer to write this answer, then to learn how to do it. Gotta learn to read documentation, not just tutorials. Tutorials are a good starting point, but once you get to more complicated matters, you need to dig deeper. Same with any new technology you want to learn.

这篇关于选中了用于过滤JTable的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆