Java 如何获取当前筛选的TableModel

Java 如何获取当前筛选的TableModel,java,jtable,rowfilter,tablerowsorter,Java,Jtable,Rowfilter,Tablerowsorter,我有下面的代码,在mouseClick事件之后,它根据JListgetSelectedItem().toString()过滤行,代码如下: try{ TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(easypath.doctorBusiness_table.getModel()); easypath.doctorBusiness_table.setRowSorter(r

我有下面的代码,在
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));

    }

下面是过滤的修改代码,创建了
eventListeners
dateSearch
stringSearch
dateStringSearch
。前两个工作正常,但第三个工作不正常,即使我尝试创建一个获取当前模型的方法。请提出建议,谢谢

为什么要在字符串搜索后获取TableModel?我说过除非你想复制所有数据并创建一个新的TableModel,否则你不能这么做

在JTable上进行过滤时,TableModel不会更改。所有数据仍存储在TableModel中。更改的是
视图
。JTable仅显示过滤的行

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

在我的评论中,我建议
使用一个带有3个条件的“andFilter”。
我尝试用多种方式解释这一点,并将其与带有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);
List filters=newarraylist(3);
所选字符串=“日产SUV”;
filters.add(RowFilter.regexFilter(“(?i)”+选中));//添加了字符串过滤器
添加(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER,startDate));
添加(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE,endDate));
RowFilter rf=RowFilter.andFilter(过滤器);
行分类器。设置行过滤器(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);
List filters=newarraylist(3);
添加(getStringFilter());
添加(getStartDateFilter());
添加(getEndDateFilter();
RowFilter rf=RowFilter.andFilter(过滤器);
行分类器。设置行过滤器(rf);

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

作为黑客,您可以创建自己的TableModel来包装整个底层JTable,监听其更新并返回JTable中显示的单元格值。这取决于您打算在何处使用此类模型,这可能是一个可怕或绝妙的想法。 请看下面的示例,了解我所说的内容。请注意,在下面的示例中侦听和事件触发功能没有正确完成。要正确侦听和响应各种模型和UI事件,需要做更多的工作,因此模型中的日期始终反映JTable的内容。从架构上讲,这种模式l不应被视为合适的模型类,但它允许其他表与底层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);
    }
}
公共类UIBasedTableModel扩展了AbstractTableModel{
专用最终JTable _参考表;
公共UIBasedTableModel(JTable underyingTable){
_underyingtable=underyingtable;
_underlyingTable.addPropertyChangeListener(“分类器”,新PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
fireTableDataChanged();
}
});
_UnderlineingTable.getModel().addTableModelListener(新的TableModelListener()){
@凌驾
公共作废表已更改(TableModelEvent e){
fireTableDataChanged();
}
});
}
@凌驾
public int getRowCount(){
返回_underyingTable.getRowCount();
}
@凌驾
public int getColumnCount(){
返回_underyingtable.getColumnCount();
}
@凌驾
公共对象getValueAt(int行索引、int列索引){
return _underyingtable.getValueAt(行索引、列索引);
}
@凌驾
公共类getColumnClass(int columnIndex){
返回_underyingtable.getColumnClass(columnIndex);
}
@凌驾
公共字符串getColumnName(int columnIndex){
返回_underyingtable.getColumnName(columnIndex);
}
}
另一种选择是自己实现类似的排序/过滤功能。这可能是一个好主意,也可能是一个坏主意,因为您必须将排序正确地集成到TableUI中


我很乐意详细说明,但必须了解您的要求。

@camickr,您弄错了,我要求重新阅读问题,直到最后,这里的问题是日期
我需要过滤过滤的行
-您需要一个“andFilter”,就像您在上一个问题中演示的那样。当您使用“&”如果if语句仅限于两个条件,或者可以使用两个以上的条件?是的,您完全正确,但我在这里提出的问题并不完全取决于日期,我在这里还提到了
JList
,其中问题不在于日期,而在于我没有根据t获得过滤表模型字符串传递了表单
JList
,我已经提供了完整的详细信息。我不是说日期。您有一个从所选列表创建的筛选条件
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);
    }
}