如何获取当前过滤的TableModel

时间:2015-07-18 19:00:54

标签: java jtable rowfilter tablerowsorter

我在下面有以下代码,其中,在mouseClick事件后,根据JList getSelectedItem().toString()过滤行,代码如下:

try{
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(easypath.doctorBusiness_table.getModel());
        easypath.doctorBusiness_table.setRowSorter(rowSorter);
        String selected = easypath.drname_jlist.getSelectedValue().toString();
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));

    }

它工作正常,并根据选定的字符串过滤行。


但是,我进一步希望根据日期过滤过滤后的模型,尽管日期过滤在DefaultTableModel上工作正常但是当我尝试传递当前的表模型时它不起作用

所以,我希望我可以在这里解释我的问题,因为我需要通过过滤的TableModel进行日期过滤。任何建议都会有所帮助。

感谢您的时间

更新

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.RowFilter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class testFilter extends javax.swing.JFrame {

    public testFilter() {
        initComponents();
    }

public void dateSearch() {
    try {
        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);

        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);

        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        rowSorter.setRowFilter(rf);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void dateString_Search(){
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel()); //  String Filtering 
        dataTable.setRowSorter(rowSorter);                                                 //  table here
        String selected = "Nissan SUV";                                                    //  to get
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));                  //  current TableModel 

        JOptionPane.showMessageDialog(null, dataTable.getRowCount()); // <--- For checking current Row Count

        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);
        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> filteredRowSorter = new TableRowSorter<>(dataTable.getModel()); //<-- Getting the current table Model After String Search
        dataTable.setRowSorter(filteredRowSorter); 
        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        filteredRowSorter.setRowFilter(rf);


    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}



private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    dataTable = new javax.swing.JTable();
    dateSearch_btn = new javax.swing.JButton();
    stringSearch_btn = new javax.swing.JButton();
    dateStringSearch_btn = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setResizable(false);

    dataTable.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {"Nissan Micra", new Date(), "20000"},
            {"Nissan SUV", new Date(), "30000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Ford Mustang", new Date(), "70000"},
            {"Ford Cobra", new Date(), "70000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "60000"},
            {"Nissan SUV", new Date(), "65000"},
            {"Nissan SUV", new Date(), "70000"},
            {"Tata Sumo", new Date(), "70000"}
        },
        new String [] {
            "Name", "Date", "Rate"
        }
    ));
    putDateInTable();
    jScrollPane1.setViewportView(dataTable);

    dateSearch_btn.setText("Date Search");
    dateSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateSearch_btnActionPerformed(evt);
        }
    });

    stringSearch_btn.setText("String Search");
    stringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            stringSearch_btnActionPerformed(evt);
        }
    });

    dateStringSearch_btn.setText("Date+String");
    dateStringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateStringSearch_btnActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(dateSearch_btn)
                    .addGap(90, 90, 90)
                    .addComponent(stringSearch_btn)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(dateStringSearch_btn)))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 223, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(dateSearch_btn)
                .addComponent(stringSearch_btn)
                .addComponent(dateStringSearch_btn))
            .addContainerGap(25, Short.MAX_VALUE))
    );

    pack();
}

private void stringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                 
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);
        String selected = "Nissan SUV";
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));
        JOptionPane.showMessageDialog(null, dataTable.getRowCount());

    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}

private void dateSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                               
    dateSearch();
}

private void dateStringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                     
    dateString_Search();
}

private void putDateInTable() {
    Date formatDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 0, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +5);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 1, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 2, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 16);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 3, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +30);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 4, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +55);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 5, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +155);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 6, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -23);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 7, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -22);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 8, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -21);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 9, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -29);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 10, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -50);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 11, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +100);


}

public static void main(String args[]) {

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new testFilter().setVisible(true);
        }
    });
}
private javax.swing.JTable dataTable;
private javax.swing.JButton dateSearch_btn;
private javax.swing.JButton dateStringSearch_btn;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton stringSearch_btn;
}

以下是经过修改的过滤代码,创建了eventListeners dateSearchstringSearchdateStringSearch。前两个工作正常但第三个工作不正常,即使我尝试创建一个获取当前模型。请建议,谢谢

2 个答案:

答案 0 :(得分:1)

不幸的是,JTable功能的设计将TableSorter及其底层RowFilter视为非模型功能。因此,它不会创建包装TableModel实例。相反,JTable直接与分拣机一起正确显示行。

作为一个hack,你可以创建自己的TableModel,它包装整个底层JTable,监听它的更新并返回它们在JTable中出现的单元格值。根据您打算使用这种模型的位置,这可能是一个可怕或绝妙的想法。 看一下下面的例子,了解我在说什么。请注意,在下面的示例中,未正确完成侦听和事件触发功能。它需要更多的工作来正确地监听和响应各种模型和UI事件,因此模型中的日期总是反映JTable的内容。从架构上讲,这个模型不应该被认为是一个合适的模型类,但它允许其他表显示与底层JTable同步的数据。

public class UIBasedTableModel extends AbstractTableModel {
    private final JTable _underlyingTable;

    public UIBasedTableModel(JTable underlyingTable) {
        _underlyingTable = underlyingTable;
        _underlyingTable.addPropertyChangeListener("sorter", new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
               fireTableDataChanged();
            }
        });
        _underlyingTable.getModel().addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                fireTableDataChanged();
            }
        });
    }

    @Override
    public int getRowCount() {
        return _underlyingTable.getRowCount();
    }

    @Override
    public int getColumnCount() {
        return _underlyingTable.getColumnCount();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return _underlyingTable.getValueAt(rowIndex, columnIndex);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return _underlyingTable.getColumnClass(columnIndex);
    }

    @Override
    public String getColumnName(int columnIndex) {
        return _underlyingTable.getColumnName(columnIndex);
    }
}

另一种选择是自己实现类似的排序/过滤功能。这可能也是一个好主意和坏主意,因为您必须将排序正确地集成到TableUI中。

我很乐意详细说明,但必须知道你的要求。

答案 1 :(得分:0)

为什么要在字符串搜索后尝试获取TableModel?我说你不能这样做unless you want to copy all the data and create a new TableModel

在对JTable进行过滤时,TableModel不会更改。所有数据仍存储在TableModel中。 View有哪些变化。 JTable仅显示已过滤的行。

为什么您的过滤器代码看起来不像Swing教程中的过滤代码?在您的代码中,您创建一个新的TableRowSorter并将其添加到表中。在Swing教程中,他们只需使用setRowFilter(...)方法重置TableRowSorter上的过滤器。这是次要的,但它告诉我你没有阅读过教程,或者如果你做了,为什么修改代码使得更复杂?

在我的评论中,我建议you have an "andFilter" with 3 conditions.我尝试用多种方式解释它与具有3个条件的if语句进行比较。当你进行“日期/字符串搜索”时,为什么你的“andFilter”只有两个条件?

我复制了“日期搜索”中的代码并进行了以下更改以创建日期/字符串过滤器:

List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
String selected = "Nissan SUV";
filters.add(RowFilter.regexFilter("(?i)" + selected)); // added the string filter
filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
rowSorter.setRowFilter(rf);

现在你有一个带有3个条件的“andFilter”。

然而,更好的设计是创建getStartDateFilter(),getEndDateFilter(),getStringFilter()等方法,这样就不会重复代码。然后你可以构建过滤器,如:

List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
filters.add(getStringFilter());
filters.add(getStartDateFilter());
filters.add(getEndDateFilter();
RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
rowSorter.setRowFilter(rf);